Адреса сокетов. Настройка адреса сокета. Системный вызов bind()

Когда сокет создан, необходимо настроить его адрес. Для этого используется системный вызов bind(). Первый параметр вызова должен содержать дескриптор сокета, для которого производится настройка адреса. Второй и третий параметры задают этот адрес.

Во втором параметре должен быть указатель на структуру struct sockaddr, содержащую удаленную и локальные части полного адреса.

Указатели типа struct sockaddr * встречаются во многих сетевых системных вызовах; они используются для передачи информации о том, к какому адресу привязан или должен быть привязан сокет. Рассмотрим этот тип данных подробнее. Структура struct sockaddr описана в файле <sys/socket.h> следующим образом:

struct sockaddr {

short sa_family;

char sa_data[14];

};

Для работы с семейством протоколов TCP/IP мы будем использовать адрес сокета следующего вида, описанного в файле <netinet/in.h>:

struct sockaddr _in{

short sin_family;

/* Избранное семейство протоколов

– всегда AF_INET */

unsigned short sin_port;

/* 16-битовый номер порта в сетевом

порядке байт */

struct in_addr sin_addr;

/* Адрес сетевого интерфейса */

char sin_zero[8];

/* Это поле не используется, но должно

всегда быть заполнено нулями */

};

Первый элемент структуры – sin_family задает семейство протоколов. В него мы будем заносить уже известную нам предопределенную константу AF_INET (см. предыдущий раздел).

Удаленная часть полного адреса – IP-адрес – содержится в структуре типа struct in_addr, с которой мы встречались в разделе "Функции преобразования IP-адресов inet_ntoa(),inet_aton()" .

Для указания номера порта предназначен элемент структуры sin_port, в котором номер порта должен храниться в сетевом порядке байт. Существует два варианта задания номерапорта: фиксированный порт по желанию пользователя и порт, который произвольно назначает операционная система. Первый вариант требует указания в качестве номера портаположительного заранее известного числа и для протокола UDP обычно используется при настройке адресов сокетов и при передаче информации с помощью системного вызова sendto()(см. следующий раздел). Второй вариант требует указания в качестве номера порта значения 0. В этом случае операционная система сама привязывает сокет к свободному номеру порта. Этот способ обычно используется при настройке сокетов программ клиентов, когда заранее точно знать номер порта для программисту необязательно.

IP–адрес при настройке также может быть определен двумя способами. Он может быть привязан к конкретному сетевому интерфейсу (т.е. сетевой плате), заставляя операционную систему принимать/передавать информацию только через этот сетевой интерфейс, а может быть привязан и ко всей вычислительной системе в целом (информация может быть получена/отослана через любой сетевой интерфейс). В первом случае в качестве значения поля структуры sin_addr.s_addr используется числовое значение IP-адреса конкретного сетевого интерфейса в сетевом порядке байт. Во втором случае это значение должно быть равно значению предопределенной константы INADDR_ANY, приведенному к сетевому порядку байт.

Третий параметр системного вызова bind() должен содержать фактическую длину структуры, адрес которой передается в качестве второго параметра. Эта длина меняется в зависимости от семейства протоколов и даже различается в пределах одного семейства протоколов. Размер структуры, содержащей адрес сокета, для семейства протоколов TCP/IP может быть определен как sizeof(struct sockaddr_in).