Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

4.4. Функция bind

Функция

bind
связывает сокет с локальным адресом протокола. В случае протоколов Интернета адрес протокола — это комбинация 32-разрядного адреса IPv4 или 128-разрядного адреса IPv6 с 16-разрядным номером порта TCP или UDP.

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen);

Возвращает: 0
в случае успешного выполнения, -1 в случае ошибки

ПРИМЕЧАНИЕ

В руководстве при описании функции bind говорилось: «функция bind присваивает имя неименованному сокету». Использование термина «имя» спорно, обычно оно вызывает ассоциацию с доменными именами (см. главу 11), такими как foo.bar.com. Функция bind не имеет ничего общего с именами. Она задает сокету адрес протокола, а что означает этот адрес — зависит от самого протокола.

Вторым аргументом является указатель на специфичный для протокола адрес, а третий аргумент — это размер структуры адреса. В случае TCP вызов функции

bind
позволяет нам задать номер порта или IP-адрес, а также задать оба эти параметра или вообще не указывать ничего.

Серверы связываются со своим заранее известным портом при запуске. Мы видели это в листинге 1.5. Если клиент или сервер TCP не делает этого, ядро выбирает динамически назначаемый порт для сокета либо при вызове функции

connect
, либо при вызове функции
listen
. Клиент TCP обычно позволяет ядру выбирать динамически назначаемый порт, если приложение не требует зарезервированного порта (см. рис. 2.10), но сервер TCP достаточно редко предоставляет ядру право выбора, так как обращение к серверам производится через заранее известные порты.

ПРИМЕЧАНИЕ

Исключением из этого правила являются серверы удаленного вызова процедур RPC (Remote Procedure Call). Обычно они позволяют ядру выбирать динамически назначаемый порт для их прослушиваемого сокета, поскольку затем этот порт регистрируется программой отображения портов RPC. Клиенты должны соединиться с этой программой, чтобы получить номер динамически назначаемого порта до того, как они смогут соединиться с сервером с помощью функции connect. Это также относится к серверам RPC, использующим протокол UDP.

С помощью функции

bind
процесс может связать конкретный IP-адрес с сокетом. IP-адрес должен соответствовать одному из интерфейсов узла. Так определяется IP-адрес, который будет использоваться для отправляемых через сокет IP-дейтаграмм. При этом для сервера TCP на сокет накладывается ограничение: он может принимать только такие входящие соединения клиента, которые предназначены именно для этого IP-адреса.

Обычно клиент TCP не связывает IP-адрес с сокетом при помощи функции

bind
. Ядро выбирает IP-адрес отправителя в момент подключения клиента к сокету, основываясь на используемом исходящем интерфейсе, который, в свою очередь, зависит от маршрута, требуемого для обращения к серверу [128, с. 737].

Если сервер TCP не связывает IP-адрес с сокетом, ядро назначает ему IP-адрес (указываемый в исходящих пакетах), который совпадает с адресом получателя сегмента SYN клиента [128, с. 943].

Как мы уже говорили, вызов функции

bind
позволяет нам задать IP-адрес
и порт (вместе или по отдельности) либо не задавать никаких аргументов. В табл. 4.5 приведены все возможные значения, которые присваиваются аргументам
sin_addr
и
sin_port
либо
sin6_addr
и
sin6_port
в зависимости от желаемого результата.

Таблица 4.5. Результаты задания IP-адреса и (или) номера порта в функции bind

Процесс задает Результат
IP-адрес Порт
Универсальный 0 Ядро выбирает IP-адрес и порт
Универсальный Ненулевое значение Ядро выбирает IP-адрес, процесс задает порт
Локальный 0 Процесс задает IP-адрес, ядро выбирает порт
Локальный Ненулевое значение Процесс задает IP-адрес и порт

Если мы зададим нулевой номер порта, то при вызове функции

bind
ядро выберет динамически назначаемый порт. Но если мы зададим IP-адрес с помощью символов подстановки, ядро не выберет локальный IP-адрес, пока к сокету не присоединится клиент (TCP) либо на сокет не будет отправлена дейтаграмма (UDP).

В случае IPv4 универсальныйадрес, состоящий из символов подстановки (wildcard), задается константой

INADDR_ANY
, значение которой обычно нулевое. Это указывает ядру на необходимость выбора IP-адреса. Пример вы видели в листинге 1.5:

struct sockaddr_in servaddr;

servaddr sin_addr s_addr = htonl(INADDR_ANY); /* универсальный */

Этот прием работает с IPv4, где IP-адрес является 32-разрядным значением, которое можно представить как простую численную константу (в данном случае 0), но воспользоваться им при работе с IPv6 мы не можем, поскольку 128-разрядный адрес IPv6 хранится в структуре. (В языке С мы не можем поместить структуру в правой части оператора присваивания.) Эта проблема решается следующим образом:

struct sockaddr_in6 serv;

serv sin6_addr = in6addr_any; /* универсальный */

Система выделяет место в памяти и инициализирует переменную

in6addr_any
, присваивая ей значение константы
IN6ADDR_ANY_INIT
. Объявление внешней константы
in6addr_any
содержится в заголовочном файле
<netinet/in.h>
.

Значение

INADDR_ANY
(0) не зависит от порядка байтов, поэтому использование функции
htonl
в действительности не требуется. Но поскольку все константы
INADDR_
, определенные в заголовочном файле
<netinet/in.h>
, задаются в порядке байтов узла, с любой из этих констант следует использовать функцию
htonl
.

Поделиться:
Популярные книги

Санек 2

Седой Василий
2. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 2

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

Без Чести

Щукин Иван
4. Жизни Архимага
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Без Чести

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный

Огненный князь

Машуков Тимур
1. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь

Ваше Сиятельство 4т

Моури Эрли
4. Ваше Сиятельство
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 4т

Вторая невеста Драконьего Лорда. Дилогия

Огненная Любовь
Вторая невеста Драконьего Лорда
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Вторая невеста Драконьего Лорда. Дилогия

Кодекс Крови. Книга V

Борзых М.
5. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга V

Девятое правило дворянина

Герда Александр
9. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Девятое правило дворянина

Цеховик. Книга 1. Отрицание

Ромов Дмитрий
1. Цеховик
Фантастика:
попаданцы
альтернативная история
5.75
рейтинг книги
Цеховик. Книга 1. Отрицание

Скрываясь в тени

Мазуров Дмитрий
2. Теневой путь
Фантастика:
боевая фантастика
7.84
рейтинг книги
Скрываясь в тени

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Идеальный мир для Лекаря 3

Сапфир Олег
3. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 3

Под маской, или Страшилка в академии магии

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.78
рейтинг книги
Под маской, или Страшилка в академии магии