LPFN_CONNECTEX función de devolución de llamada (mswsock.h)
La función ConnectEx establece una conexión a un socket especificado y, opcionalmente, envía datos una vez establecida la conexión. La función ConnectEx solo se admite en sockets orientados a la conexión.
Sintaxis
LPFN_CONNECTEX LpfnConnectex;
BOOL LpfnConnectex(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen,
[in, optional] PVOID lpSendBuffer,
[in] DWORD dwSendDataLength,
[out] LPDWORD lpdwBytesSent,
[in] LPOVERLAPPED lpOverlapped
)
{...}
Parámetros
[in] s
Descriptor que identifica un socket no conectado y enlazado previamente. Vea Comentarios para obtener más información.
[in] name
Un puntero a .
una estructura sockaddr que especifica la dirección a la que se va a conectar. Para IPv4, el sockaddr contiene AF_INET para la familia de direcciones, la dirección IPv4 de destino y el puerto de destino. Para IPv6, la estructura sockaddr contiene AF_INET6 para la familia de direcciones, la dirección IPv6 de destino, el puerto de destino y puede contener información adicional sobre el flujo IPv6 y el identificador de ámbito.
[in] namelen
Longitud, en bytes, de la estructura sockaddr a la que apunta el parámetro name .
[in, optional] lpSendBuffer
Puntero al búfer que se va a transferir después de establecer una conexión. Este parámetro es opcional. Si la opción TCP_FASTOPEN está habilitada en s antes de llamar a ConnectEx , es posible que se envíen algunos de estos datos durante el establecimiento de la conexión.
[in] dwSendDataLength
Longitud, en bytes, de datos a los que apunta el parámetro lpSendBuffer . Este parámetro se omite cuando el parámetro lpSendBuffer es NULL.
[out] lpdwBytesSent
Si se devuelve correctamente, este parámetro apunta a un valor DWORD que indica el número de bytes que se enviaron después de establecer la conexión. Los bytes enviados proceden del búfer al que apunta el parámetro lpSendBuffer . Este parámetro se omite cuando el parámetro lpSendBuffer es NULL.
[in] lpOverlapped
Estructura SUPERPUESTA que se usa para procesar la solicitud. Se debe especificar el parámetro lpOverlapped y no puede ser NULL.
Valor devuelto
Si se ejecuta correctamente, la función ConnectEx devuelve TRUE. En caso de error, la función devuelve FALSE. Use la función WSAGetLastError para obtener información de error extendida. Si una llamada a la función WSAGetLastError devuelve ERROR_IO_PENDING, la operación se inició correctamente y está en curso. En tales circunstancias, la llamada puede seguir produciendo un error cuando se completa la operación superpuesta.
Si el código de error devuelto es WSAECONNREFUSED, WSAENETUNREACH o WSAETIMEDOUT, la aplicación puede llamar a ConnectEx, WSAConnect o conectarse de nuevo en el mismo socket.
Código de error | Descripción |
---|---|
Se debe realizar una llamada de función WSAStartup correcta antes de usar ConnectEx. | |
Error en el subsistema de red. | |
La dirección local del socket ya está en uso y el socket no se marcó para permitir la reutilización de direcciones con SO_REUSEADDR. Este error suele producirse durante una operación de enlace , pero el error podría retrasarse hasta que se llama a una función ConnectEx , si se llamó a la función bind con una dirección comodín (INADDR_ANY o in6addr_any) especificada para la dirección IP local. La función ConnectEx debe enlazar implícitamente una dirección IP específica. | |
Una llamada de función Connect, WSAConnect o ConnectEx sin bloqueo está en curso en el socket especificado. | |
La dirección remota no es una dirección válida, como ADDR_ANY (la función ConnectEx solo se admite para sockets orientados a la conexión). | |
Las direcciones de la familia especificada no se pueden usar con este socket. | |
El intento de conexión se rechazó. | |
El parámetro name, lpSendBuffer o lpOverlapped no es una parte válida del espacio de direcciones del usuario o namelen es demasiado pequeño. | |
El parámetro s es un socket independiente o de escucha. | |
El socket ya está conectado. | |
La red no se puede alcanzar desde este host en estos momentos. | |
Se intentó realizar una operación de socket a un host inalcanzable. | |
No hay espacio de búfer disponible; el socket no se puede conectar. | |
El descriptor no es un socket. | |
Se ha agotado el tiempo de espera de la conexión sin poder establecer una conexión. |
Comentarios
La función ConnectEx combina varias funciones de socket en una sola transición de API o kernel. Las siguientes operaciones se realizan cuando una llamada a la función ConnectEx se completa correctamente:
- Se establece una nueva conexión.
- Se envía un bloque opcional de datos después de establecer la conexión.
En el caso de las aplicaciones destinadas a Windows Vista y versiones posteriores, considere la posibilidad de usar la función WSAConnectByList o WSAConnectByName que simplifica considerablemente el diseño de aplicaciones cliente.
La función ConnectEx solo se puede usar con sockets orientados a la conexión. El socket pasado en el parámetro s debe crearse con un tipo de socket de SOCK_STREAM, SOCK_RDM o SOCK_SEQPACKET.
El parámetro lpSendBuffer apunta a un búfer de datos que se enviará después de establecer la conexión. El parámetro dwSendDataLength especifica la longitud en bytes de estos datos que se van a enviar. Una aplicación puede solicitar enviar un gran búfer de datos mediante ConnectEx de la misma manera que se pueden usar las funciones send y WSASend . Pero se recomienda encarecidamente a los desarrolladores que envíen un búfer enorme en una sola llamada mediante ConnectEx, ya que esta operación usa una gran cantidad de recursos de memoria del sistema hasta que se haya enviado todo el búfer.
Si la función ConnectEx se realiza correctamente, se estableció una conexión y todos los datos a los que apunta el parámetro lpSendBuffer se enviaron a la dirección especificada en la estructura sockaddr a la que apunta el parámetro name .
La función ConnectEx usa E/S superpuesta. Como resultado, la función ConnectEx permite a una aplicación atender un gran número de clientes con relativamente pocos subprocesos. Por el contrario, la función WSAConnect , que no usa E/S superpuesta, normalmente requiere un subproceso independiente para atender cada solicitud de conexión cuando se reciben solicitudes simultáneas.
Los sockets orientados a la conexión a menudo no pueden completar su conexión inmediatamente y, por tanto, la operación se inicia y la función vuelve inmediatamente con el error ERROR_IO_PENDING o WSA_IO_PENDING. Cuando se completa la operación de conexión y se logra el éxito o error, se notifica el estado mediante el mecanismo de notificación de finalización indicado en lpOverlapped. Al igual que con todas las llamadas de función superpuestas, puede usar eventos o puertos de finalización como mecanismo de notificación de finalización. El parámetro lpNumberOfBytesTransferred de la función GetQueuedCompletionStatus o GetOverlappedResult o WSAGetOverlappedResult indica el número de bytes enviados en la solicitud.
Cuando la función ConnectEx se completa correctamente, los identificadores de socket solo se pueden pasar a las funciones siguientes:
Si se llama a la función TransmitFile en un socket conectado previamente con marcas de TF_DISCONNECT y TF_REUSE_SOCKET, el socket especificado se devuelve a un estado en el que no está conectado, pero sigue enlazado. En tales casos, el identificador del socket se puede pasar a la función ConnectEx en su parámetro s , pero el socket no se puede reutilizar en una llamada de función AcceptEx . Del mismo modo, el socket aceptado reutilizado mediante la función TransmitFile no se puede usar en una llamada a ConnectEx. Tenga en cuenta que, en el caso de un socket reutilizado, ConnectEx está sujeto al comportamiento del transporte subyacente. Por ejemplo, un socket TCP puede estar sujeto al estado de TIME_WAIT TCP, lo que hace que la llamada a ConnectEx se retrase.
Cuando la función ConnectEx 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 );
La función getockopt se puede usar con la opción de socket SO_CONNECT_TIME para comprobar si se ha establecido una conexión mientras ConnectEx está en curso. Si se ha establecido una conexión, el valor devuelto en el parámetro optval pasado a la función getockopt es el número de segundos que se ha conectado el socket. Si el socket no está conectado, el parámetro optval devuelto contiene 0xFFFFFFFF. Es necesario comprobar una conexión de esta manera para determinar si las conexiones se han establecido durante un período de tiempo sin enviar datos; en tales casos, se recomienda que dichas conexiones finalicen.
Por ejemplo:
//Need to #include <mswsock.h> for SO_CONNECT_TIME
int seconds;
int bytes = sizeof(seconds);
int iResult = 0;
iResult = getsockopt( s, SOL_SOCKET, SO_CONNECT_TIME,
(char *)&seconds, (PINT)&bytes );
if ( iResult != NO_ERROR ) {
printf( "getsockopt(SO_CONNECT_TIME) failed with error: %u\n",
WSAGetLastError() );
}
else {
if (seconds == 0xFFFFFFFF)
printf("Connection not established yet\n");
else
printf("Connection has been established %ld seconds\n",
seconds);
}
Si el parámetro address de la estructura sockaddr al que apunta el parámetro name es ceros, ConnectEx devuelve el error WSAEADDRNOTAVAIL. Cualquier intento de volver a conectar una conexión activa producirá un error con el código de error WSAEISCONN.
Cuando se cierra un socket conectado por cualquier motivo, se recomienda descartar el socket y crear un nuevo socket. El razonamiento de esto es que es más seguro suponer que, cuando las cosas van awry en un socket conectado por cualquier motivo, la aplicación debe descartar el socket y crear el socket necesario de nuevo para volver a un punto estable.
Si se llama a la función DisconnectEx con la marca TF_REUSE_SOCKET , el socket especificado se devuelve a un estado en el que no está conectado, pero sigue enlazado. En tales casos, el identificador del socket se puede pasar a la función ConnectEx en su parámetro s .
El intervalo de tiempo que debe transcurrir antes de que TCP pueda liberar una conexión cerrada y reutilizar sus recursos se conoce como estado de TIME_WAIT o 2MSL. Durante este tiempo, la conexión se puede volver a abrir a un costo mucho menor para el cliente y el servidor que establecer una nueva conexión.
El comportamiento de TIME_WAIT se especifica en RFC 793, que requiere que TCP mantenga una conexión cerrada durante un intervalo al menos igual al doble de la duración máxima del segmento (MSL) de la red. Cuando se libera una conexión, su par de sockets y los recursos internos usados para el socket se pueden usar para admitir otra conexión.
Windows TCP se revierte a un estado de TIME_WAIT posterior al cierre de una conexión. Aunque en el estado TIME_WAIT, no se puede reutilizar un par de sockets. El período de TIME_WAIT se puede configurar modificando la siguiente configuración del Registro DWORD que representa el período de TIME_WAIT en segundos.
HKEY_LOCAL_MACHINE\Sistema\Currentcontrolset\Servicios\TCPIP\Parámetros\TcpTimedWaitDelay
De forma predeterminada, el MSL se define como 120 segundos. El valor predeterminado del Registro TcpTimedWaitDelay es un valor de 240 segundos, que representa 2 veces la duración máxima del segmento de 120 segundos o 4 minutos. Sin embargo, puede usar esta entrada para personalizar el intervalo.
Reducir el valor de esta entrada permite que TCP libere las conexiones cerradas con mayor rapidez, lo que proporciona más recursos para nuevas conexiones. Sin embargo, si el valor es demasiado bajo, TCP podría liberar recursos de conexión antes de que se complete la conexión, lo que requiere que el servidor use recursos adicionales para volver a establecer la conexión.
Esta configuración del Registro se puede establecer de 0 a 300 segundos.
Windows Phone 8: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.
Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP] |
Servidor mínimo compatible | Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | mswsock.h |