socklen_t
Аргумент sockfd
— это дескриптор сокета, возвращенный функцией socket
. Второй и третий аргументы — это указатель на структуру адреса сокета и ее размер (см. раздел 3.3). Структура адреса сокета должна содержать IP-адрес и номер порта сервера. Пример применения этой функции был представлен в листинге 1.1.
Клиенту нет необходимости вызывать функцию bind
(которую мы описываем в следующем разделе) до вызова функции connect
: при необходимости ядро само выберет и динамически назначаемый порт, и IP-адрес отправителя.
В случае сокета TCP функция connect
инициирует трехэтапное рукопожатие TCP (см. раздел 2.6). Функция возвращает значение, только если установлено соединение или произошла ошибка. Возможно несколько ошибок:
1. Если клиент TCP не получает ответа на свой сегмент SYN, возвращается сообщение ETIMEDOUT
. 4.4BSD, например, отправляет один сегмент SYN, когда вызывается функция connect
, второй — 6 с спустя, и еще один — через 24 с [128, с. 828]. Если ответ не получен в течение 75 с, возвращается ошибка.
Некоторые системы позволяют администратору устанавливать значение времени ожидания; см. приложение Е [111].
2. Если на сегмент SYN сервер отвечает сегментом RST, это означает, что ни один процесс на узле сервера не находится в ожидании подключения к указанному нами порту (например, нужный процесс может быть не запущен). Это ECONNREFUSED
сразу же по получении им сегмента RST.
RST (от «reset» — сброс) — это сегмент TCP, отправляемый собеседнику при возникновении ошибок. Вот три условия, при которых генерируется RST: сегмент SYN приходит для порта, не имеющего прослушивающего сервера (что мы только что описали); TCP хочет разорвать существующее соединение; TCP получает сегмент для несуществующего соединения (дополнительная информация содержится на с. 246–250 [111]).
3. Если сегмент SYN клиента приводит к получению сообщения ICMP о недоступности получателя от какого-либо промежуточного маршрутизатора, это считается EHOSTUNREACH
, либо как ENETUNREACH
. Может случиться, что удаленная система будет недоступна по любому маршруту из таблицы маршрутизации локального узла, или что возврат из connect
произойдет без всякого ожидания.
Многие более ранние системы, такие как 4.2BSD, некорректно прерывали попытки установления соединения при получении сообщения ICMP о недоступности получателя. Это было неверно, поскольку данная ошибка ICMP может указывать на временную неисправность. Например, может быть так, что эта ошибка вызвана проблемой маршрутизации, которая исправляется в течение 15 с.
Обратите внимание, что мы не включили ENETUNREACH в табл. А.5 несмотря на то, что сеть получателя действительно может быть недоступна. Недоступность сети считается устаревшей ошибкой, и даже если 4.4BSD получает такое сообщение, приложению возвращается EHOSTUNREACH.
Эти ошибки мы можем наблюдать на примере нашего простого клиента, созданного в листинге 1.1. Сначала мы указываем адрес нашего собственного узла (127.0.0.1), на котором работает сервер времени и даты, и видим обычный вывод:
solaris % daytimetcpcli 127.0.0.1
Sun Jul 27 22:01:51 2003
Укажем IP-адрес другого компьютера (HP-UX):
solaris % daytimecpcli 192.6.38.100
Sun Jul 27 22:04:59 PDT 2003
Затем мы задаем IP-адрес в локальной подсети (192.168.1/24) с несуществующим адресом узла (100). Когда клиент посылает запросы ARP (запрашивая аппаратный адрес узла), он не получает никакого ответа:
solaris % daytimetcpcli 192.168.1.100
connect error: Connection timed out