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.
[in] nodename
Cadena terminada en NULL que contiene el nombre del host o la dirección IP del host en la que se va a conectar para IPv4 o IPv6.
[in] servicename
Cadena terminada en NULL que 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 que usan 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 el búfer LocalAddress rellenado por el sistema tras completar correctamente la llamada.
[out] LocalAddress
Puntero a la estructura SOCKADDR 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 búfer RemoteAddress 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 el búfer remoteAddress rellenado por el sistema tras completar correctamente la llamada.
[out] RemoteAddress
Puntero a la estructura SOCKADDR 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 RemoteAddressLength .
[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 los parámetros TRUE y LocalAddress y RemoteAddress se rellenan si el autor de la llamada proporcionó estos búferes.
Si se produce un error en la llamada, se devuelve FALSE . A continuación, se puede llamar a WSAGetLastError para obtener información de error extendida.
Código devuelto | Descripción |
---|---|
|
El host pasado como parámetro nodename no era accesible. |
|
Se pasó un parámetro no válido a la función. El parámetro nodename o servicename no debe ser NULL. El parámetro Reserved debe ser NULL. |
|
No se pudo asignar memoria suficiente. |
|
Se pasó un socket no válido a la función. El parámetro s no debe ser INVALID_SOCKET ni NULL. |
|
No se recibió una respuesta de la aplicación remota antes de que se superara el parámetro de tiempo de espera . |
Comentarios
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 setsockopt en un socket creado para la familia de direcciones AF_INET6 para deshabilitar la opción de socket IPV6_V6ONLY antes de llamar a WSAConnectByName. Esto se logra mediante una llamada a la función setsockopt en el socket con el parámetro level establecido en IPPROTO_IPV6 (vea IPPROTO_IPV6 Opciones de socket), el parámetro optname establecido en IPV6_V6ONLY y el valor del 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 o el comportamiento de no bloqueo. WSAConnectByName se 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, se debe usar WSAConnect en su lugar.
En versiones anteriores a Windows 10, si una aplicación necesita enlazarse a una dirección o puerto local específica, no se puede usar WSAConnectByName, ya que el parámetro de socket para WSAConnectByName debe ser un socket independiente.
Esta restricción se quitó Windows 10.
Los parámetros RemoteAddress y 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 se pase realmente en estos parámetros. Por lo tanto, para las direcciones IPv4, un puntero a una estructura de sockaddr_in se convertirá en un puntero a SOCKADDR como los parámetros RemoteAddress y LocalAddress . En el caso de las direcciones IPv6, un puntero a una estructura de sockaddr_in6 se convertiría en un puntero a SOCKADDR como los parámetros RemoteAddress y LocalAddress .
Cuando la función WSAConnectByName devuelve TRUE, el socket s está en el estado predeterminado de 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 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 );
Windows 8.1 y Windows Server 2012 R2: la función WSAConnectByNameW es compatible con 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 Convenciones para prototipos de función.
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP] |
Servidor mínimo compatible | Windows Server 2008 [aplicaciones de escritorio | aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | winsock2.h |
Library | Ws2_32.lib |
Archivo DLL | Ws2_32.dll |