connect - инициирует соединение на сокете
connect(2)
инициирует соединение на сокете
ОБЗОР
#include <sys/types.h> /* Смотрите
ЗАМЕЧАНИЯ */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ОПИСАНИЕ
Системный вызов
connect() устанавливает соединение с сокетом, заданным
файловый дескриптором
sockfd, ссылающимся на адрес
addr. Аргумент
addrlen определяет размер
addr. Формат адреса в
addr определяется
адресным пространством сокета
sockfd; подробнее можно узнать в
socket(2).
Если сокет sockfd имеет тип SOCK_DGRAM, то адрес addr является
адресом по умолчанию, куда посылаются датаграммы, и единственным адресом,
откуда они принимаются. Если сокет имеет тип SOCK_STREAM или
SOCK_SEQPACKET, то данный системный вызов попытается установить
соединение с другим сокетом, заданным параметром addr.
Обычно сокеты с протоколами, основанными на соединении, могут устанавливать
соединение connect() только один раз; сокеты с протоколами без
установления соединения могут использовать connect() многократно, чтобы
изменить адрес назначения. Сокеты без установления соединения могут
прекратить связь с другим сокетом, установив член sa_family структуры
sockaddr в AF_UNSPEC (в Linux поддерживается, начиная с ядра версии
2.2).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Если соединение или привязка прошла успешно, возвращается ноль. При ошибке
возвращается -1, а
errno устанавливается должным образом.
ОШИБКИ
Ниже приведены только общие ошибки сокетов. Могут также появляться коды
ошибок, существующие в конкретном домене.
EACCES
Для доменных сокетов UNIX, которые идентифицируются по имени пути: нет прав
на запись в файл сокета, или в одном из каталогов пути запрещён
поиск. (См. также path_resolution(7).)
EACCES, EPERM
Пользователь попытался соединиться с широковещательным адресом, не установив
широковещательный флаг на сокете или же запрос на соединение завершился
неудачно из-за правила локального межсетевого экрана.
EADDRINUSE
Локальный адрес уже используется.
EADDRNOTAVAIL
(доменные сокеты Интернета) Сокет, указанный sockfd, ранее не был
привязан к адресу и при попытке привязать его к эфемеридному порту, было
определено, что все номера в диапазоне эфемеридных портов уже
используются. Смотрите обсуждение /proc/sys/net/ipv4/ip_local_port_range
в ip(7).
EAFNOSUPPORT
Адрес имеет некорректное семейство адресов в поле sa_family.
EAGAIN
Недостаточно элементов в кэше маршрутизации.
EALREADY
Сокет является неблокирующим, а предыдущая попытка установить соединение ещё
не завершилась.
EBADF
Значение sockfd не является правильным открытым файловым дескриптором.
ECONNREFUSED
Ничто не слушает удалённый адрес.
EFAULT
Адрес структуры сокета находится за пределами пользовательского адресного
пространства.
EINPROGRESS
Сокет является неблокирующим, а соединение не может быть установлено
немедленно. Можно использовать select(2) или poll(2), чтобы закончить
соединение, установив ожидание возможности записи в сокет. После того, как
select(2) сообщит о такой возможности, используйте getsockopt(2),
чтобы прочитать флаг SO_ERROR на уровне SOL_SOCKET, чтобы определить,
успешно ли завершился connect() (в этом случае SO_ERROR равен нулю)
или неудачно (тогда SO_ERROR равен одному из обычных кодов ошибок,
перечисленных здесь, и объясняет причину неудачи).
EINTR
Системный вызов был прерван пойманным сигналом; см. signal(7).
EISCONN
Соединение на сокете уже произошло.
ENETUNREACH
Сеть недоступна.
ENOTSOCK
Файловый дескриптор sockfd указывает не на каталог.
EPROTOTYPE
Тип сокета не поддерживается запрошенным протоколом связи. Это ошибка может
возникать при попытке подключить доменный датаграммный сокет UNIX к
потоковому сокету.
ETIMEDOUT
Произошел тайм-аут во время ожидания соединения. Сервер, возможно, очень
занят и не может принимать новые соединения. Заметьте, что для IP-сокетов
тайм-аут может быть очень длинным, если на сервере разрешено использование
syncookies.
СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD, (вызов
connect() впервые
появился в 4.2BSD).
ЗАМЕЧАНИЯ
В POSIX.1 не требуется включение
<sys/types.h>, и этот
заголовочный файл не требуется в Linux. Однако, для некоторых старых
реализаций (BSD) требует данный файл, и в переносимых приложениях для
предосторожности, вероятно, лучше его указать.
Третий аргумент connect() в действительности имеет тип int (а в 4.x
BSD, libc4 и libc5 это так и есть). Некоторый беспорядок POSIX сказавшийся
на настоящей socklen_t, также используется в glibc. См. также
accept(2).
Если вызов connect() завершается с ошибкой, то состояние сокета считается
неопределённым. Переносимые приложения должны закрывать сокет и для
переподключения создавать новый.
ПРИМЕР
Пример использования
connect() показан в
getaddrinfo(3).