Функция WSAConnectByNameA (winsock2.h)
Функция WSAConnectByName устанавливает соединение с указанным узлом и портом. Эта функция предоставляется для быстрого подключения к конечной точке сети с учетом имени узла и порта.
Эта функция поддерживает адреса IPv4 и IPv6.
BOOL WSAConnectByNameA(
[in] SOCKET s,
[in] LPCSTR nodename,
[in] LPCSTR servicename,
[in, out] LPDWORD LocalAddressLength,
[out] LPSOCKADDR LocalAddress,
[in, out] LPDWORD RemoteAddressLength,
[out] LPSOCKADDR RemoteAddress,
[in] const timeval *timeout,
LPWSAOVERLAPPED Reserved
);
[in] s
Дескриптор, идентифицирующий несвязанный сокет.
[in] nodename
Строка, завершающаяся значением NULL, которая содержит имя узла или IP-адрес узла, к которому нужно подключиться для IPv4 или IPv6.
[in] servicename
Строка с завершением NULL, содержащая имя службы или порт назначения узла, к которому нужно подключиться для IPv4 или IPv6.
Имя службы — это строковый псевдоним для номера порта. Например, "http" — это псевдоним порта 80, определенный целевой группой по проектированию в Интернете (IETF) в качестве порта по умолчанию, используемого веб-серверами для протокола HTTP. Возможные значения параметра servicename , если номер порта не указан, перечислены в следующем файле:
%WINDIR%\system32\drivers\etc\services
[in, out] LocalAddressLength
На входных данных — указатель на размер буфера LocalAddress в байтах , предоставленного вызывающим объектом. В выходных данных — указатель на размер (в байтах) SOCKADDR для локального адреса, хранящегося в буфере LocalAddress , заполненном системой после успешного завершения вызова.
[out] LocalAddress
Указатель на структуру SOCKADDR , которая получает локальный адрес подключения. Размер параметра точно совпадает с размером, возвращенным в LocalAddressLength. Это те же сведения, которые будут возвращены функцией getsockname . Этот параметр может иметь значение NULL. В этом случае параметр LocalAddressLength игнорируется.
[in, out] RemoteAddressLength
На входных данных — указатель на размер буфера RemoteAddress в байтах , предоставленного вызывающим объектом. На выходе — указатель на размер (в байтах) SOCKADDR для удаленного адреса, хранящегося в буфере RemoteAddress , заполненного системой после успешного завершения вызова.
[out] RemoteAddress
Указатель на структуру SOCKADDR , которая получает удаленный адрес подключения. Это те же сведения, которые будут возвращены функцией getpeername . Этот параметр может иметь значение NULL. В этом случае RemoteAddressLength игнорируется.
[in] timeout
Время (в миллисекундах) ожидания ответа от удаленного приложения перед прерыванием вызова.
Reserved
Зарезервировано для будущей реализации. Этот параметр должен иметь значение NULL.
Если соединение установлено, WSAConnectByName возвращает значение TRUE , а параметры LocalAddress и RemoteAddress заполняются, если эти буферы были предоставлены вызывающим объектом.
Если вызов завершается сбоем, возвращается значение FALSE . Затем можно вызвать WSAGetLastError для получения расширенных сведений об ошибке.
Код возврата | Описание |
---|---|
|
Узел, переданный в качестве параметра nodename , был недостижим. |
|
В функцию передан недопустимый параметр. Параметр nodename или servicename не должен иметь значение NULL. Параметр Reserved должен иметь значение NULL. |
|
Не удалось выделить достаточный объем памяти. |
|
В функцию передан недопустимый сокет. Параметр s не должен быть INVALID_SOCKET или NULL. |
|
Ответ от удаленного приложения не был получен до превышения времени ожидания . |
WSAConnectByName предоставляется для быстрого и прозрачного подключения к удаленным узлам на определенных портах. Он совместим с версиями IPv6 и IPv4.
Чтобы включить обмен данными по протоколам IPv6 и IPv4, используйте следующий метод:
- Функция setsockopt должна вызываться в сокете, созданном для семейства адресов AF_INET6, чтобы отключить параметр сокета IPV6_V6ONLY перед вызовом WSAConnectByName. Это достигается путем вызова функции setsockopt в сокете с параметром уровня , равным IPPROTO_IPV6 (см . IPPROTO_IPV6 Параметры сокета), параметру optname присвоено значение IPV6_V6ONLY, а значение параметра optvalue равно нулю.
WSAConnectByName имеет ограничения: он работает только для сокетов, ориентированных на подключение, таких как сокеты типа SOCK_STREAM. Функция не поддерживает перекрывающееся или неблокирующее поведение. WSAConnectByName будет блокироваться, даже если сокет находится в неблокирующем режиме.
WSAConnectByName не поддерживает предоставленные пользователем данные во время установки подключения. Этот вызов также не поддерживает структуры FLOWSPEC. В случаях, когда эти функции необходимы, следует использовать WSAConnect .
В версиях, предшествующих Windows 10, если приложению необходимо выполнить привязку к определенному локальному адресу или порту, использовать WSAConnectByName нельзя, так как параметр сокета для WSAConnectByName должен быть несвязанным сокетом.
Это ограничение было удалено Windows 10.
Параметры RemoteAddress и LocalAddress указывают на структуру SOCKADDR , которая является универсальным типом данных. При вызове WSAConnectByName ожидается, что в этих параметрах будет передаваться тип адреса сокета, относящегося к используемому сетевому протоколу или семейству адресов. Поэтому для IPv4-адресов указатель на структуру sockaddr_in будет приведен к указателю на SOCKADDR в качестве параметров RemoteAddress и LocalAddress . Для IPv6-адресов указатель на структуру sockaddr_in6 будет приведен к указателю на SOCKADDR в качестве параметров RemoteAddress и LocalAddress .
Когда функция WSAConnectByName возвращает значение TRUE, сокеты будут в состоянии по умолчанию для подключенного сокета. Сокет не включает ранее заданные свойства или параметры до тех пор, пока в сокете не будет задано SO_UPDATE_CONNECT_CONTEXT. Используйте функцию setsockopt , чтобы задать параметр SO_UPDATE_CONNECT_CONTEXT.
Пример:
//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT
int iResult = 0;
iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );
Windows 8.1 и Windows Server 2012 R2. Функция WSAConnectByNameW поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версий.
Установите подключение с помощью WSAConnectByName.
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <mswsock.h> // Need for SO_UPDATE_CONNECT_CONTEXT
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
SOCKET
OpenAndConnect(LPWSTR NodeName, LPWSTR PortName)
{
SOCKET ConnSocket = INVALID_SOCKET;
int ipv6only = 0;
int iResult;
BOOL bSuccess;
SOCKADDR_STORAGE LocalAddr = {0};
SOCKADDR_STORAGE RemoteAddr = {0};
DWORD dwLocalAddr = sizeof(LocalAddr);
DWORD dwRemoteAddr = sizeof(RemoteAddr);
ConnSocket = socket(AF_INET6, SOCK_STREAM, 0);
if (ConnSocket == INVALID_SOCKET){
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
if (iResult == SOCKET_ERROR){
wprintf(L"setsockopt for IPV6_V6ONLY failed with error: %d\n",
WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
bSuccess = WSAConnectByName(ConnSocket, NodeName,
PortName, &dwLocalAddr,
(SOCKADDR*)&LocalAddr,
&dwRemoteAddr,
(SOCKADDR*)&RemoteAddr,
NULL,
NULL);
if (!bSuccess){
wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, SOL_SOCKET,
SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
if (iResult == SOCKET_ERROR){
wprintf(L"setsockopt for SO_UPDATE_CONNECT_CONTEXT failed with error: %d\n",
WSAGetLastError());
closesocket(ConnSocket);
return INVALID_SOCKET;
}
return ConnSocket;
}
int __cdecl wmain(int argc, wchar_t **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
SOCKET s = INVALID_SOCKET;
// Validate the parameters
if (argc != 3) {
wprintf(L"usage: %ws <Nodename> <Portname>\n", argv[0]);
wprintf(L"wsaconnectbyname establishes a connection to a specified host and port.\n");
wprintf(L"%ws www.contoso.com 8080\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return 1;
}
wprintf(L"WsaConnectByName with following parameters:\n");
wprintf(L"\tNodename = %ws\n", argv[1]);
wprintf(L"\tPortname (or port) = %ws\n\n", argv[2]);
//--------------------------------
// Call our function that uses the WsaConnectByName.
s = OpenAndConnect(argv[1], argv[2]);
if ( s == INVALID_SOCKET ) {
wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
{
wprintf(L"WsaConnectByName succeeded\n");
closesocket(s);
WSACleanup();
return 0;
}
}
Примечание
Заголовок winsock2.h определяет WSAConnectByName в качестве псевдонима, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОД. Использование псевдонима, не зависящий от кодирования, с кодом, который не является нейтральным для кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или времени выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.
Требование | Значение |
---|---|
Минимальная версия клиента | Windows 8.1, Windows Vista [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows Server 2008 [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | winsock2.h |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |