Функция connect (winsock2.h)
Функция connect устанавливает соединение с указанным сокетом.
Синтаксис
int WSAAPI connect(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
Параметры
[in] s
Дескриптор, определяющий неподключенные сокеты.
[in] name
Указатель на структуру sockaddr, с которой должно быть установлено соединение.
[in] namelen
Длина структуры sockaddr в байтах, на которую указывает параметр name .
Возвращаемое значение
Если ошибка не возникает, функция connect возвращает ноль. В противном случае он возвращает SOCKET_ERROR, и конкретный код ошибки можно получить, вызвав WSAGetLastError.
В блокирующем сокете возвращаемое значение указывает на успешное или неудачное завершение попытки подключения.
При использовании неблокированного сокета попытка подключения не может быть завершена немедленно. В этом случае connect вернет SOCKET_ERROR, а WSAGetLastError — WSAEWOULDBLOCK. В этом случае возможны три сценария:
- Используйте функцию select , чтобы определить завершение запроса на подключение, проверив, доступен ли сокет для записи.
- Если приложение использует WSAsyncSelect для указания интереса к событиям подключения, приложение получит FD_CONNECT уведомление о том, что операция подключения завершена (успешно или нет).
- Если приложение использует WSAEventSelect для указания интереса к событиям подключения, то связанный объект события будет сигнализировать о том, что операция подключения завершена (успешно или нет).
Пока попытка подключения не завершится в неблокизоваемом сокете, все последующие вызовы для подключения к одному и тому же сокету будут завершаться ошибкой с кодом WSAEALREADY и WSAEISCONN после успешного завершения подключения. Из-за неоднозначности в версии 1.1 спецификации Windows Sockets коды ошибок, возвращаемые из подключения , пока подключение уже находится в состоянии ожидания, могут отличаться в зависимости от реализации. Поэтому приложениям не рекомендуется использовать несколько вызовов для подключения для обнаружения завершения подключения. В этом случае они должны быть готовы обрабатывать значения ошибок WSAEINVAL и WSAEWOULDBLOCK так же, как и WSAEALREADY, чтобы обеспечить надежную работу.
Если возвращенный код ошибки указывает на сбой попытки подключения (то есть WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT), приложение может снова вызвать подключение для того же сокета.
Код ошибки | Значение |
---|---|
Перед использованием этой функции должен произойти успешный вызов WSAStartup . | |
Произошел сбой сетевой подсистемы. | |
Локальный адрес сокета уже используется, и сокет не помечен, чтобы разрешить повторное использование адреса с SO_REUSEADDR. Эта ошибка обычно возникает при выполнении привязки, но может быть отложена до функции connect , если привязка была к адресу с подстановочными знаками (INADDR_ANY или in6addr_any) для локального IP-адреса. Конкретный адрес должен быть неявно привязан функцией connect . | |
Блокирующий вызов Windows Socket 1.1 был отменен через WSACancelBlockingCall. | |
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова. | |
Для указанного сокета выполняется неблокировка вызова подключения .
Примечание Чтобы сохранить обратную совместимость, эта ошибка сообщается как WSAEINVAL приложениям Windows Sockets 1.1, которые связаны с Winsock.dll или Wsock32.dll.
|
|
Удаленный адрес не является допустимым адресом (например , INADDR_ANY или in6addr_any). | |
Адреса из заданного семейства адресов не могут использоваться с этим сокетом. | |
Попытка подключения была принудительно отклонена. | |
Структура sockaddr, на которую указывает имя , содержит неправильный формат адреса для связанного семейства адресов или параметр namelen слишком мал. Эта ошибка также возвращается, если структура sockaddr , на которую указывает параметр name с длиной, указанной в параметре namelen, не находится в допустимой части адресного пространства пользователя. | |
Параметр s является сокетом прослушивания. | |
Сокет уже подключен (только для сокетов, ориентированных на подключение). | |
В настоящее время сеть недоступна с этого узла. | |
Сделана попытка выполнить операцию на сокете для недоступного хоста. | |
Примечание Буферное пространство недоступно. Не удается подключить сокет.
|
|
Дескриптор, указанный в параметре s, не является сокетом. | |
Время ожидания попытки подключения истекло без установления соединения. | |
Сокет помечается как неблокируемый, и подключение не может быть завершено немедленно. | |
Не удалось подключить сокет датаграммы к широковещательным адресам, так как параметр setsockopt SO_BROADCAST не включен. |
Комментарии
Функция connect используется для создания подключения к указанному назначению. Если для сокетов нет ограничений, система назначает уникальные значения локальной связи, а сокет помечается как привязанный.
Для сокетов, ориентированных на подключение (например, тип SOCK_STREAM), активное подключение инициируется к внешнему узлу с использованием имени (адрес в пространстве имен сокета; подробное описание см. в разделе bind and sockaddr).
После успешного завершения вызова сокета сокет будет готов к отправке и получению данных. Если адресный элемент структуры, указанной параметром name , заполнен нулями, подключение вернет ошибку WSAEADDRNOTAVAIL. Любая попытка повторно подключить активное подключение завершится ошибкой с кодом WSAEISCONN.
Для неблокированных сокетов, ориентированных на подключение, часто не удается завершить подключение немедленно. В этом случае эта функция возвращает ошибку WSAEWOULDBLOCK. Однако операция продолжается.
Когда об успешном или неудачном результате становится известно, это может быть сообщено одним из двух способов в зависимости от того, как клиент регистрирует уведомление.
- Если клиент использует функцию select , успешное выполнение отображается в наборе writefds, а сбой — в наборе exceptfds.
- Если клиент использует функции WSAsyncSelect или WSAEventSelect, уведомление будет объявлено с FD_CONNECT, а код ошибки, связанный с FD_CONNECT, указывает на успешное выполнение или конкретную причину сбоя.
Если подключение не завершено немедленно, клиент должен дождаться завершения подключения, прежде чем пытаться задать параметры сокета с помощью setsockopt. Вызов setsockopt во время подключения не поддерживается.
Для сокета без подключения (например, тип SOCK_DGRAM) операция, выполняемая с помощью connect , заключается в том, чтобы установить адрес назначения по умолчанию, который можно использовать при последующей отправке/ вызовов WSASend и recv/ WSARecv . Все датаграммы, полученные с адреса, отличного от указанного адреса назначения, будут удалены. Если адресный элемент структуры, указанной по имени , заполнен нулями, сокет будет отключен. Затем удаленный адрес по умолчанию будет неопределенным, поэтому отправка/ вызовов WSASend и recv/ WSARecv вернет код ошибки WSAENOTCONN. Однако по-прежнему можно использовать sendto/ WSASendTo и recvf from/ WSARecvFrom . Назначение по умолчанию можно изменить, просто повторно вызвав connect , даже если сокет уже подключен. Все датаграммы, помещенные в очередь для получения, удаляются, если имя отличается от имени предыдущего подключения.
Для сокетов без подключения имя может указывать любой допустимый адрес, включая широковещательный адрес. Однако для подключения к адресу широковещательной рассылки сокет должен использовать setsockopt , чтобы включить параметр SO_BROADCAST. В противном случае подключение завершится ошибкой с кодом WSAEACCES.
При разрыве соединения между сокетами необходимо удалить подключенный сокет и создать новый сокет. Когда проблема возникает в подключенном сокете, приложение должно удалить сокет и создать сокет снова, чтобы вернуться к стабильной точке.
Пример кода
В следующем примере показано использование функции connect .#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(27015);
//----------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
Еще один пример, в котором используется функция connect, см. в разделе начало работы с Winsock.
Заметки о сокетах IrDA
- Файл заголовка Af_irda.h должен быть явно включен.
- При обнаружении существующего подключения IrDA на уровне доступа к мультимедиа возвращается WSAENETDOWN .
- Если активные подключения к устройству с другим адресом существуют, возвращается WSAEADDRINUSE .
- Если сокет уже подключен или не удалось изменить монопольный или мультиплексный режим, возвращается WSAEISCONN .
- Если сокет был ранее привязан к имени локальной службы для приема входящих подключений с помощью привязки, возвращается WSAEINVAL . Обратите внимание, что после привязки сокета его нельзя использовать для установки исходящего подключения.
IrDA реализует функцию connect с адресами формы sockaddr_irda. Как правило, клиентское приложение создает сокет с функцией сокета, сканирует ближайшие устройства IrDA с помощью параметра сокета IRLMP_ENUMDEVICES, выбирает устройство из возвращаемого списка, формирует адрес и вызывает подключение. Между блокирующей и неблокирующей семантикой нет никакой разницы.
Требования
Минимальная версия клиента | Windows Vista [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows Server 2003 [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | winsock2.h |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |