Функция 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 |