Michael J. Donahoo "TCP/IP Sockets in C, 2nd Edition" / Michael J. Donahoo "Программирование TCP/IP сокетов в Си, 2-ое издание": 2.6 Привязка к адресу
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
2.6 Привязка к адресу victor8632 15.04.13 в 13:55 |
|
|
Чтобы это заработало, сервер должен быть связан с этим адресом и портом. victor8632 17.04.13 в 12:59 |
||
|
Это может быть выполнено при помощи функции bind(). victor8632 17.04.13 в 13:00 |
||
|
Напомним еще раз, что клиент получает адрес сервера при помощи функции connect(), но сервер определяет свой собственный адрес при помощи функции bind(). victor8632 17.04.13 в 13:03 |
||
|
Ни клиент, ни сервер приложений не нуждаются в адресе клиента для поддержки общения. (Конечно, сервер может захотеть узнать адрес клиента для регистрации или для других целей.) victor8632 17.04.13 в 13:11 |
||
|
int bind(int socket, struct sockaddr *localAddress, socklen_t addressSize) victor8632 17.04.13 в 13:12 |
||
|
Первый параметр является указателем, который возвращен ранее при вызове функции socket(). victor8632 17.04.13 в 13:13 |
||
|
Как и для функции connect() параметр адреса определяется как указатель на структуру sockaddr, но для TCP/IP приложений он всегда будет указателем на структуру sockaddr_in (для IPv4) или sockaddr_in6 (для IPv6), содержащую интернет адрес локального интерфейса и порт, связанный с ним. victor8632 17.04.13 в 13:18 |
||
|
Параметр addressSize определяет размер адресной структуры. bind() возвращает 0 при успешном выполнении и -1 при неудаче. victor8632 17.04.13 в 13:21 |
||
|
Важно понимать, что для программы невозможно связать сокет с любым интернет адресом - если задан интернет адрес (любого типа), вызов будет успешным только в том случае, если заданный адрес будет адресом сетевого интерфейса компьютера, на котором программа запущена. victor8632 17.04.13 в 13:31 |
||
|
Сервер на компьютере с несколькими интернет адресами может связать только один из них, потому что только на этот адрес захочет принимать запросы на соединение. victor8632 17.04.13 в 13:43 |
||
|
Обычно, однако, сервер хочет принимать соединения на различные адреса хоста (компьютера) и для этого адресная часть структуры sockaddr устанавливается равной "символическому" адресу inaddr_any для IPv4 или in6addr_any для IPv6. victor8632 25.06.13 в 12:50 |
||
|
Семантика "символического" адреса состоит в том, что он соответствует любому конкретному адресу. victor8632 25.06.13 в 12:52 |
||
|
Для сервера это означает, что он будет принимать соединения, адресованные любому адресу хоста (конкретного типа). victor8632 25.06.13 в 12:53 |
||
|
В то время как bind() применяется преимущественно на серверах, клиент также может использовать bind() для определения своего локального адреса/порта. victor8632 25.06.13 в 12:56 |
||
|
Для тех TCP клиентов, которые не определяют свой собственный локальный адрес/порт при помощи bind(), локальный интернет адрес и порт определяются во время вызова connect(). victor8632 25.06.13 в 13:00 |
||
|
Таким образом, клиент должен вызвать bind() перед вызовом connect(), если он собирается его использовать. victor8632 25.06.13 в 13:03 |
||
|
Вы можете инициализировать структуру in6_addr символическим адресом in6addr_any_init; однако, эта специальная константа может использоваться только в качестве инициализирующей в декларации. victor8632 25.06.13 в 13:07 |
||
|
Следует отметить, что пока inaddr_any определена в основном порядке байтов, и, соответственно она должна быть преобразована в сетевой порядок байтов при помощи функции htonl() перед использованием в качестве аргумента bind(), in6addr_any и in6addr_any_init изначально находятся в представлении сетевого порядка байтов. victor8632 25.06.13 в 13:21 |
||
|
Наконец, если вы установите порт равным 0 в bind(), система будет подбирать для вас неиспользованный локальный порт. victor8632 25.06.13 в 13:09 |
