Compartilhar via


Função WSAConnectByNameA (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 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
);

Parâmetros

[in] s

Um descritor que identifica um soquete não conectado.

Observação no Windows 7, Windows Server 2008 R2 e anterior, a função WSAConnectByName requer um soquete não associado e não conectado. Isso difere de outras chamadas winsock para estabelecer uma conexão (por exemplo, WSAConnect).
 

[in] nodename

Uma cadeia de caracteres NULLterminada 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 NULLterminada 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 de nome de serviço 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 de LocalAddress fornecido pelo chamador. Na saída, um ponteiro para o tamanho, em bytes, da 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 em RemoteAddress buffer 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, o 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.

Valor de retorno

Se uma conexão for estabelecida, WSAConnectByName retornará verdadeiro e localAddress e parâmetros RemoteAddress serão preenchidos se esses buffers forem fornecidos pelo chamador.

Se a chamada falhar, FALSE será retornado. WSAGetLastError pode ser chamado para obter informações de erro estendidas.

Código de retorno Descrição
WSAEHOSTUNREACH
O host passou como o parâmetro nodename era inacessível.
WSAEINVAL
Um parâmetro inválido foi passado para a função. O nodename ou o parâmetro servicename não deve ser NULL. O parâmetro Reservado deve ser NULL.
WSAENOBUFS
Não foi possível alocar memória suficiente.
WSAENOTSOCK
Um soquete inválido foi passado para a função. O parâmetro do não deve ser INVALID_SOCKET ou NULL.
WSAETIMEDOUT
Uma resposta do aplicativo remoto não foi recebida antes que o parâmetro tempo limite fosse excedido.

Observações

WSAConnectByName é fornecido para habilitar conexões rápidas e transparentes para 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 para 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 de de nome definido como IPV6_V6ONLYe o valor do parâmetro de valor de definido como zero.

WSAConnectByName tem limitações: ele funciona apenas para soquetes orientados à conexão, como os do tipo SOCK_STREAM. A função não dá suporte a comportamentos de E/S sobrepostos ou não bloqueados. WSAConnectByName será bloqueada mesmo se o soquete estiver no modo de não bloqueio.

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, WSAConnect devem ser usados.

Em versões antes do Windows 10, se um aplicativo precisar se associar a um endereço ou porta local específico, 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 do Windows 10.

Os parâmetros RemoteAddress e LocalAddress apontam para uma estrutura de 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 de 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 de 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 está no estado padrão de um soquete conectado. O soquete não habilita as 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 );

Observação Ao emitir uma chamada winsock de bloqueio, como WSAConnectByName com o parâmetro de tempo limite definido como NULL, o Winsock pode precisar aguardar um evento de rede antes que a chamada possa ser concluída. O Winsock executa uma espera alertável nessa situação, que pode ser interrompida por uma APC (chamada de procedimento assíncrono) agendada no mesmo thread. A emissão de outra chamada winsock de bloqueio dentro de um APC que interrompeu uma chamada Winsock de bloqueio contínuo no mesmo thread levará a um comportamento indefinido e nunca deve ser tentada pelos clientes winsock.
 
Windows Phone 8: a função WSAConnectByNameW tem suporte para aplicativos da Windows Phone Store no Windows Phone 8 e posterior.

windows 8.1 e Windows Server 2012 R2: a função WSAConnectByNameW tem suporte para aplicativos da Windows Store no Windows 8.1, Windows Server 2012 R2 e posterior.

Exemplos

Estabelecer 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;
    }
}

Nota

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 do pré-processador UNICODE. A combinação do uso do alias neutro de codificação com código que não é neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Conventions for Function Prototypes.

Requisitos

Requisito Valor
de cliente com suporte mínimo Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP]
servidor com suporte mínimo Windows Server 2008 [aplicativos da área de trabalho | Aplicativos UWP]
da Plataforma de Destino Windows
cabeçalho winsock2.h
biblioteca Ws2_32.lib
de DLL Ws2_32.dll

Consulte também

opções de soquete IPPROTO_IPV6

SOCKADDR

WSAConnect

WSAConnectByList

WSAGetLastError

getaddrinfo

getpeername

de nome de choque

setsockopt