Função WSAConnectByNameW (winsock2.h)
A função WSAConnectByName estabelece uma conexão com um host e uma porta especificados. Essa função é fornecida para permitir uma conexão rápida com um ponto de extremidade de rede, considerando um nome de host e uma porta.
Essa função dá suporte a endereços IPv4 e IPv6.
Sintaxe
BOOL WSAConnectByNameW(
[in] SOCKET s,
[in] LPWSTR nodename,
[in] LPWSTR servicename,
[in, out] LPDWORD LocalAddressLength,
[out] LPSOCKADDR LocalAddress,
[in, out] LPDWORD RemoteAddressLength,
[out] LPSOCKADDR RemoteAddress,
[in] const timeval *timeout,
LPWSAOVERLAPPED Reserved
);
Parâmetros
[in] s
Um descritor que identifica um soquete não conectado.
[in] nodename
Uma cadeia de caracteres terminada em NULL que contém o nome do host ou o endereço IP do host no qual se conectar para IPv4 ou IPv6.
[in] servicename
Uma cadeia de caracteres terminada em NULL que contém o nome do serviço ou a porta de destino do host no qual se conectar para IPv4 ou IPv6.
Um nome de serviço é um alias de cadeia de caracteres para um número de porta. Por exemplo, "http" é um alias para a porta 80 definido pela IETF (Internet Engineering Task Force) como a porta padrão usada pelos servidores Web para o protocolo HTTP. Os valores possíveis para o parâmetro servicename quando um número de porta não é especificado são listados no seguinte arquivo:
%WINDIR%\system32\drivers\etc\services
[in, out] LocalAddressLength
Na entrada, um ponteiro para o tamanho, em bytes, do buffer LocalAddress fornecido pelo chamador. Na saída, um ponteiro para o tamanho, em bytes, do SOCKADDR para o endereço local armazenado no buffer LocalAddress preenchido pelo sistema após a conclusão bem-sucedida da chamada.
[out] LocalAddress
Um ponteiro para a estrutura SOCKADDR que recebe o endereço local da conexão. O tamanho do parâmetro é exatamente o tamanho retornado em LocalAddressLength. Essas são as mesmas informações que seriam retornadas pela função getsockname . Esse parâmetro pode ser NULL; nesse caso, o parâmetro LocalAddressLength é ignorado.
[in, out] RemoteAddressLength
Na entrada, um ponteiro para o tamanho, em bytes, do buffer RemoteAddress fornecido pelo chamador. Na saída, um ponteiro para o tamanho, em bytes, do SOCKADDR para o endereço remoto armazenado no buffer RemoteAddress preenchido pelo sistema após a conclusão bem-sucedida da chamada.
[out] RemoteAddress
Um ponteiro para a estrutura SOCKADDR que recebe o endereço remoto da conexão. Essas são as mesmas informações que seriam retornadas pela função getpeername . Esse parâmetro pode ser NULL; nesse caso, RemoteAddressLength é ignorado.
[in] timeout
O tempo, em milissegundos, para aguardar uma resposta do aplicativo remoto antes de anular a chamada.
Reserved
Reservado para implementação futura. Esse parâmetro deve ser definido como NULL.
Retornar valor
Se uma conexão for estabelecida, WSAConnectByName retornará os parâmetros TRUE e LocalAddress e RemoteAddress serão preenchidos se esses buffers forem fornecidos pelo chamador.
Se a chamada falhar, FALSE será retornado. O WSAGetLastError pode ser chamado para obter informações de erro estendidas.
Código de retorno | Descrição |
---|---|
|
O host passado como o parâmetro nodename estava inacessível. |
|
Um parâmetro inválido foi passado para a função. O parâmetro nodename ou servicename não deve ser NULL. O parâmetro Reserved deve ser NULL. |
|
Não foi possível alocar memória suficiente. |
|
Um soquete inválido foi passado para a função . O parâmetro s não deve ser INVALID_SOCKET ou NULL. |
|
Uma resposta do aplicativo remoto não foi recebida antes que o parâmetro de tempo limite fosse excedido. |
Comentários
O WSAConnectByName é fornecido para habilitar conexões rápidas e transparentes com hosts remotos em portas específicas. Ele é compatível com as versões IPv6 e IPv4.
Para habilitar as comunicações IPv6 e IPv4, use o seguinte método:
- A função setsockopt deve ser chamada em um soquete criado para a família de endereços AF_INET6 desabilitar a opção de soquete IPV6_V6ONLY antes de chamar WSAConnectByName. Isso é feito chamando a função setsockopt no soquete com o parâmetro de nível definido como IPPROTO_IPV6 (consulte IPPROTO_IPV6 Opções de Soquete), o parâmetro optname definido como IPV6_V6ONLY e o valor do parâmetro optvalue definido como zero.
O WSAConnectByName tem limitações: funciona apenas para soquetes orientados à conexão, como aqueles do tipo SOCK_STREAM. A função não dá suporte a E/S sobreposta ou comportamento sem bloqueio. WSAConnectByName será bloqueado mesmo se o soquete estiver no modo sem bloqueio.
O WSAConnectByName não dá suporte a dados fornecidos pelo usuário durante o estabelecimento de uma conexão. Essa chamada também não dá suporte a estruturas FLOWSPEC. Nos casos em que esses recursos são necessários, o WSAConnect deve ser usado.
Em versões antes de Windows 10, se um aplicativo precisar ser associado a um endereço ou porta local específico, o WSAConnectByName não poderá ser usado, pois o parâmetro de soquete para WSAConnectByName deve ser um soquete não associado.
Essa restrição foi removida Windows 10.
Os parâmetros RemoteAddress e LocalAddress apontam para uma estrutura SOCKADDR , que é um tipo de dados genérico. Quando WSAConnectByName é chamado, espera-se que um tipo de endereço de soquete específico para o protocolo de rede ou família de endereços que está sendo usado seja realmente passado nesses parâmetros. Portanto, para endereços IPv4, um ponteiro para uma estrutura sockaddr_in seria convertido em um ponteiro para SOCKADDR como os parâmetros RemoteAddress e LocalAddress . Para endereços IPv6, um ponteiro para uma estrutura sockaddr_in6 seria convertido em um ponteiro para SOCKADDR como os parâmetros RemoteAddress e LocalAddress .
Quando a função WSAConnectByName retorna TRUE, o soquete s está no estado padrão de um soquete conectado. O soquete s não habilita propriedades ou opções definidas anteriormente até que SO_UPDATE_CONNECT_CONTEXT seja definido no soquete. Use a função setsockopt para definir a opção SO_UPDATE_CONNECT_CONTEXT.
Por exemplo:
//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 e Windows Server 2012 R2: a função WSAConnectByNameW tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posterior.
Exemplos
Estabeleça uma conexão usando 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;
}
}
Observação
O cabeçalho winsock2.h define WSAConnectByName como um alias que seleciona automaticamente a versão ANSI ou Unicode dessa função com base na definição da constante de pré-processador UNICODE. Misturar o uso do alias neutro de codificação com código que não seja neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Convenções para protótipos de função.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP] |
Servidor mínimo com suporte | Windows Server 2008 [aplicativos da área de trabalho | Aplicativos UWP] |
Plataforma de Destino | Windows |
Cabeçalho | winsock2.h |
Biblioteca | Ws2_32.lib |
DLL | Ws2_32.dll |