Поделиться через


Функция 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, а WSAGetLastErrorWSAEWOULDBLOCK. В этом случае возможны три сценария:

  • Используйте функцию select , чтобы определить завершение запроса на подключение, проверив, доступен ли сокет для записи.
  • Если приложение использует WSAsyncSelect для указания интереса к событиям подключения, приложение получит FD_CONNECT уведомление о том, что операция подключения завершена (успешно или нет).
  • Если приложение использует WSAEventSelect для указания интереса к событиям подключения, то связанный объект события будет сигнализировать о том, что операция подключения завершена (успешно или нет).

Пока попытка подключения не завершится в неблокизоваемом сокете, все последующие вызовы для подключения к одному и тому же сокету будут завершаться ошибкой с кодом WSAEALREADY и WSAEISCONN после успешного завершения подключения. Из-за неоднозначности в версии 1.1 спецификации Windows Sockets коды ошибок, возвращаемые из подключения , пока подключение уже находится в состоянии ожидания, могут отличаться в зависимости от реализации. Поэтому приложениям не рекомендуется использовать несколько вызовов для подключения для обнаружения завершения подключения. В этом случае они должны быть готовы обрабатывать значения ошибок WSAEINVAL и WSAEWOULDBLOCK так же, как и WSAEALREADY, чтобы обеспечить надежную работу.

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

Код ошибки Значение
WSANOTINITIALISED
Перед использованием этой функции должен произойти успешный вызов WSAStartup .
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEADDRINUSE
Локальный адрес сокета уже используется, и сокет не помечен, чтобы разрешить повторное использование адреса с SO_REUSEADDR. Эта ошибка обычно возникает при выполнении привязки, но может быть отложена до функции connect , если привязка была к адресу с подстановочными знаками (INADDR_ANY или in6addr_any) для локального IP-адреса. Конкретный адрес должен быть неявно привязан функцией connect .
WSAEINTR
Блокирующий вызов Windows Socket 1.1 был отменен через WSACancelBlockingCall.
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEALREADY
Для указанного сокета выполняется неблокировка вызова подключения .
Примечание Чтобы сохранить обратную совместимость, эта ошибка сообщается как WSAEINVAL приложениям Windows Sockets 1.1, которые связаны с Winsock.dll или Wsock32.dll.
 
WSAEADDRNOTAVAIL
Удаленный адрес не является допустимым адресом (например , INADDR_ANY или in6addr_any).
WSAEAFNOSUPPORT
Адреса из заданного семейства адресов не могут использоваться с этим сокетом.
WSAECONNREFUSED
Попытка подключения была принудительно отклонена.
WSAEFAULT
Структура sockaddr, на которую указывает имя , содержит неправильный формат адреса для связанного семейства адресов или параметр namelen слишком мал. Эта ошибка также возвращается, если структура sockaddr , на которую указывает параметр name с длиной, указанной в параметре namelen, не находится в допустимой части адресного пространства пользователя.
WSAEINVAL
Параметр s является сокетом прослушивания.
WSAEISCONN
Сокет уже подключен (только для сокетов, ориентированных на подключение).
WSAENETUNREACH
В настоящее время сеть недоступна с этого узла.
WSAEHOSTUNREACH
Сделана попытка выполнить операцию на сокете для недоступного хоста.
WSAENOBUFS
Примечание Буферное пространство недоступно. Не удается подключить сокет.
 
WSAENOTSOCK
Дескриптор, указанный в параметре s, не является сокетом.
WSAETIMEDOUT
Время ожидания попытки подключения истекло без установления соединения.
WSAEWOULDBLOCK
Сокет помечается как неблокируемый, и подключение не может быть завершено немедленно.
WSAEACCES
Не удалось подключить сокет датаграммы к широковещательным адресам, так как параметр setsockopt SO_BROADCAST не включен.

Комментарии

Функция connect используется для создания подключения к указанному назначению. Если для сокетов нет ограничений, система назначает уникальные значения локальной связи, а сокет помечается как привязанный.

Для сокетов, ориентированных на подключение (например, тип SOCK_STREAM), активное подключение инициируется к внешнему узлу с использованием имени (адрес в пространстве имен сокета; подробное описание см. в разделе bind and sockaddr).

Примечание Если открывается сокет, выполняется вызов setsockopt , а затем выполняется вызов sendto , Windows Sockets выполняет неявный вызов функции привязки .

 

После успешного завершения вызова сокета сокет будет готов к отправке и получению данных. Если адресный элемент структуры, указанной параметром 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.

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

Примечание При выполнении блокирующего вызова Winsock, например connect, Winsock может потребоваться дождаться сетевого события, прежде чем вызов сможет завершиться. В этой ситуации Winsock выполняет оповещенное ожидание, которое может быть прервано асинхронным вызовом процедуры (APC), запланированным в том же потоке. Выполнение другого блокирующего вызова Winsock внутри APC, который прервал текущий блокирующий вызов Winsock в том же потоке, приведет к неопределенному поведению и никогда не должен выполняться клиентами Winsock.
 

Пример кода

В следующем примере показано использование функции 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

См. также раздел

WSAsyncSelect

WSAConnect

ConnectEx

Функции Winsock

Справочник по Winsock

Принять

bind

getsockname

select

sockaddr

Сокета