Готовый перевод Michael J. Donahoo "TCP/IP Sockets in C, 2nd Edition" / Michael J. Donahoo "Программирование TCP/IP сокетов в Си, 2-ое издание": 2.6 Привязка к адресу

Внимание! Этот перевод, возможно, ещё не готов, так как модераторы установили для него статус «идёт перевод»

2.6 Привязка к адресу

Как мы уже отмечали, клиент и сервер назначают "рандеву" на адресе и порту сервера.

Чтобы это заработало, сервер должен быть связан с этим адресом и портом.

Это может быть выполнено при помощи функции bind().

Напомним еще раз, что клиент получает адрес сервера при помощи функции connect(), но сервер определяет свой собственный адрес при помощи функции bind().

Ни клиент, ни сервер приложений не нуждаются в адресе клиента для поддержки общения. (Конечно, сервер может захотеть узнать адрес клиента для регистрации или для других целей.)

int bind(int socket, struct sockaddr *localAddress, socklen_t addressSize)

Первый параметр является указателем, который возвращен ранее при вызове функции socket().

Как и для функции connect() параметр адреса определяется как указатель на структуру sockaddr, но для TCP/IP приложений он всегда будет указателем на структуру sockaddr_in (для IPv4) или sockaddr_in6 (для IPv6), содержащую интернет адрес локального интерфейса и порт, связанный с ним.

Параметр addressSize определяет размер адресной структуры. bind() возвращает 0 при успешном выполнении и -1 при неудаче.

Важно понимать, что для программы невозможно связать сокет с любым интернет адресом - если задан интернет адрес (любого типа), вызов будет успешным только в том случае, если заданный адрес будет адресом сетевого интерфейса компьютера, на котором программа запущена.

Сервер на компьютере с несколькими интернет адресами может связать только один из них, потому что только на этот адрес захочет принимать запросы на соединение.

Обычно, однако, сервер хочет принимать соединения на различные адреса хоста (компьютера) и для этого адресная часть структуры sockaddr устанавливается равной "символическому" адресу inaddr_any для IPv4 или in6addr_any для IPv6.

Семантика "символического" адреса состоит в том, что он соответствует любому конкретному адресу.

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

В то время как bind() применяется преимущественно на серверах, клиент также может использовать bind() для определения своего локального адреса/порта.

Для тех TCP клиентов, которые не определяют свой собственный локальный адрес/порт при помощи bind(), локальный интернет адрес и порт определяются во время вызова connect().

Таким образом, клиент должен вызвать bind() перед вызовом connect(), если он собирается его использовать.

Вы можете инициализировать структуру in6_addr символическим адресом in6addr_any_init; однако, эта специальная константа может использоваться только в качестве инициализирующей в декларации.

Следует отметить, что пока inaddr_any определена в основном порядке байтов, и, соответственно она должна быть преобразована в сетевой порядок байтов при помощи функции htonl() перед использованием в качестве аргумента bind(), in6addr_any и in6addr_any_init изначально находятся в представлении сетевого порядка байтов.

Наконец, если вы установите порт равным 0 в bind(), система будет подбирать для вас неиспользованный локальный порт.

Внимание! Этот перевод, возможно, ещё не готов.
Его статус: идёт перевод

Переведено на Нотабеноиде
http://notabenoid.org/book/29398/102493

Переводчики: victor8632

Настройки

Готово:

100.00% КП = 1.0