Compartir a través de


Función WSAConnectByNameA (winsock2.h)

La función WSAConnectByName establece una conexión a un host y puerto especificados. Esta función se proporciona para permitir una conexión rápida a un punto de conexión de red dado un nombre de host y un puerto.

Esta función admite direcciones IPv4 e IPv6.

Sintaxis

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

Descriptor que identifica un socket no conectado.

Nota en Windows 7, Windows Server 2008 R2 y versiones anteriores, la función WSAConnectByName requiere un socket no enlazado y no conectado. Esto difiere de otras llamadas de Winsock para establecer una conexión (por ejemplo, WSAConnect).
 

[in] nodename

Un cadena terminada en NULLque contiene el nombre del host o la dirección IP del host en el que se va a conectar para IPv4 o IPv6.

[in] servicename

Un cadena terminada en NULLque contiene el nombre del servicio o el puerto de destino del host en el que se va a conectar para IPv4 o IPv6.

Un nombre de servicio es un alias de cadena para un número de puerto. Por ejemplo, "http" es un alias para el puerto 80 definido por el Grupo de tareas de ingeniería de Internet (IETF) como el puerto predeterminado usado por los servidores web para el protocolo HTTP. Los valores posibles para el parámetro servicename cuando no se especifica un número de puerto se muestran en el siguiente archivo:

%WINDIR%\system32\drivers\etc\services

[in, out] LocalAddressLength

En la entrada, un puntero al tamaño, en bytes, del búfer LocalAddress proporcionado por el autor de la llamada. En la salida, un puntero al tamaño, en bytes, del SOCKADDR para la dirección local almacenada en la LocalAddress búfer rellenado por el sistema tras completar correctamente la llamada.

[out] LocalAddress

Puntero a la estructura SOCKADDR de que recibe la dirección local de la conexión. El tamaño del parámetro es exactamente el tamaño devuelto en LocalAddressLength. Esta es la misma información que devolvería la función getsockname. Este parámetro puede ser NULL, en cuyo caso se omite el parámetro LocalAddressLength.

[in, out] RemoteAddressLength

En la entrada, un puntero al tamaño, en bytes, del RemoteAddress búfer proporcionado por el autor de la llamada. En la salida, un puntero al tamaño, en bytes, del SOCKADDR para la dirección remota almacenada en RemoteAddress búfer rellenado por el sistema tras completar correctamente la llamada.

[out] RemoteAddress

Puntero a la estructura SOCKADDR de que recibe la dirección remota de la conexión. Esta es la misma información que devolvería la función getpeername. Este parámetro puede ser null, en cuyo caso se omite el remoteAddressLength de .

[in] timeout

El tiempo, en milisegundos, para esperar una respuesta de la aplicación remota antes de anular la llamada.

Reserved

Reservado para la implementación futura. Este parámetro debe establecerse en NULL.

Valor devuelto

Si se establece una conexión, WSAConnectByName devuelve TRUE y localAddress y parámetros RemoteAddress se rellenan si el autor de la llamada proporcionó estos búferes.

Si se produce un error en la llamada, se devuelve FALSE. WSAGetLastError se puede llamar para obtener información de error extendida.

Código devuelto Descripción
WSAEHOSTUNREACH
El host que se pasa como el parámetro nodename no se puede acceder.
WSAEINVAL
Se pasó un parámetro no válido a la función . El nodename o el parámetro servicename no debe ser NULL. El parámetro reserved debe ser NULL.
WSAENOBUFS
No se pudo asignar memoria suficiente.
WSAENOTSOCK de
Se pasó un socket no válido a la función . El parámetro de no debe ser INVALID_SOCKET ni NULL.
WSAETIMEDOUT
No se recibió una respuesta de la aplicación remota antes de que se superara el tiempo de espera parámetro.

Observaciones

WSAConnectByName se proporciona para habilitar conexiones rápidas y transparentes a hosts remotos en puertos específicos. Es compatible con las versiones IPv6 e IPv4.

Para habilitar las comunicaciones IPv6 e IPv4, use el método siguiente:

  • Se debe llamar a la función setockopt en un socket creado para que la familia de direcciones AF_INET6 deshabilite la opción de socket de IPV6_V6ONLY antes de llamar a WSAConnectByName. Esto se logra llamando a la función setockopt de en el socket con el parámetro de nivel de establecido en IPPROTO_IPV6 (vea IPPROTO_IPV6 Opciones de socket), el parámetro optname establecido en IPV6_V6ONLYy el valor de parámetro optvalue establecido en cero .

WSAConnectByName tiene limitaciones: solo funciona para sockets orientados a la conexión, como los de tipo SOCK_STREAM. La función no admite la E/S superpuesta ni el comportamiento de no bloqueo. WSAConnectByName bloqueará incluso si el socket está en modo de no bloqueo.

WSAConnectByName no admite datos proporcionados por el usuario durante el establecimiento de una conexión. Esta llamada tampoco admite estructuras FLOWSPEC. En los casos en los que se requieren estas características, WSAConnect deben usarse en su lugar.

En versiones anteriores a Windows 10, si una aplicación necesita enlazarse a una dirección o puerto local específica, WSAConnectByName no se puede usar, ya que el parámetro socket para WSAConnectByName debe ser un socket sin enlazar.

Esta restricción se quitó windows 10.

El RemoteAddress y los parámetros LocalAddress apuntan a una estructura SOCKADDR, que es un tipo de datos genérico. Cuando se llama a WSAConnectByName, se espera que un tipo de dirección de socket específico del protocolo de red o la familia de direcciones que se use realmente se pasen en estos parámetros. Por lo tanto, para las direcciones IPv4, un puntero a una estructura de sockaddr_in se convertiría en un puntero a SOCKADDR como remoteAddress y parámetros LocalAddress. Para las direcciones IPv6, un puntero a una estructura de sockaddr_in6 se convertiría en un puntero a SOCKADDR como parámetros RemoteAddress y LocalAddress.

Cuando la función WSAConnectByName devuelve TRUE, el socket s está en estado predeterminado para un socket conectado. El socket s no habilita las propiedades o opciones establecidas previamente hasta que SO_UPDATE_CONNECT_CONTEXT se establece en el socket. Use la función setsockopt de para establecer la opción SO_UPDATE_CONNECT_CONTEXT.

Por ejemplo:

//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT

int iResult = 0;

iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );

Nota Al emitir una llamada de Winsock de bloqueo, como WSAConnectByName con el parámetro tiempo de espera establecido en NULL, Winsock puede necesitar esperar un evento de red antes de que se pueda completar la llamada. Winsock realiza una espera alertable en esta situación, que se puede interrumpir mediante una llamada de procedimiento asincrónica (APC) programada en el mismo subproceso. La emisión de otra llamada winsock de bloqueo dentro de un APC que interrumpió una llamada de Winsock en curso en el mismo subproceso provocará un comportamiento indefinido y los clientes winsock nunca deben intentarlo.
 
Windows Phone 8: La función WSAConnectByNameW de es compatible con las aplicaciones de la Tienda de Windows Phone en Windows Phone 8 y versiones posteriores.

windows 8.1 y Windows Server 2012 R2: la función WSAConnectByNameW se admite para las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

Ejemplos

Establezca una conexión mediante 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

El encabezado winsock2.h define WSAConnectByName como alias que selecciona automáticamente la versión ANSI o Unicode de esta función en función de la definición de la constante de preprocesador UNICODE. La combinación del uso del alias neutral de codificación con código que no es neutral de codificación puede dar lugar a errores de coincidencia que dan lugar a errores de compilación o tiempo de ejecución. Para obtener más información, vea Conventions for Function Prototypes.

Requisitos

Requisito Valor
cliente mínimo admitido Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP]
servidor mínimo admitido Windows Server 2008 [aplicaciones de escritorio | Aplicaciones para UWP]
de la plataforma de destino de Windows
encabezado de winsock2.h
biblioteca de Ws2_32.lib
DLL de Ws2_32.dll

Consulte también

IPPROTO_IPV6 opciones de socket

SOCKADDR

WSAConnect

WSAConnectByList

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt