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.

Nota Esta función es una extensión específica de Microsoft para la especificación de Windows Sockets.

 

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
WSANOTINITIALISED
Se debe realizar una llamada de función WSAStartup correcta antes de usar ConnectEx.
WSAENETDOWN
Error en el subsistema de red.
WSAEADDRINUSE
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.
WSAEALREADY
Una llamada de función Connect, WSAConnect o ConnectEx sin bloqueo está en curso en el socket especificado.
WSAEADDRNOTAVAIL
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).
WSAEAFNOSUPPORT
Las direcciones de la familia especificada no se pueden usar con este socket.
WSAECONNREFUSED
El intento de conexión se rechazó.
WSAEFAULT
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.
WSAEINVAL
El parámetro s es un socket independiente o de escucha.
WSAEISCONN
El socket ya está conectado.
WSAENETUNREACH
La red no se puede alcanzar desde este host en estos momentos.
WSAEHOSTUNREACH
Se intentó realizar una operación de socket a un host inalcanzable.
WSAENOBUFS
No hay espacio de búfer disponible; el socket no se puede conectar.
WSAENOTSOCK
El descriptor no es un socket.
WSAETIMEDOUT
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 .

Nota El puntero de función para la función ConnectEx debe obtenerse en tiempo de ejecución realizando una llamada a la función WSAIoctl con el SIO_GET_EXTENSION_FUNCTION_POINTER código de operación especificado. El búfer de entrada pasado a la función WSAIoctl debe contener WSAID_CONNECTEX, un identificador único global (GUID) cuyo valor identifica la función de extensión ConnectEx . Si se ejecuta correctamente, la salida devuelta por la función WSAIoctl contiene un puntero a la función ConnectEx . El GUID de WSAID_CONNECTEX se define en el archivo de encabezado Mswsock.h .
 

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.

Nota Todas las E/S iniciadas por un subproceso determinado se cancelan cuando se cierra ese subproceso. En el caso de los sockets superpuestos, las operaciones asincrónicas pendientes pueden producir un error si el subproceso está cerrado antes de que se completen las operaciones. Consulte ExitThread para obtener más información.

 

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

Nota Si se abre un socket, se realiza una llamada a setsockopt y, a continuación, se realiza una llamada sendto , Windows Sockets realiza una llamada de función de enlace implícita.
 

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

Consulte también

AcceptEx

DisconnectEx

ExitThread

GetOverlappedResult

GetQueuedCompletionStatus

OVERLAPPED

ReadFile

TransmitFile

WSAConnect

WSAConnectByList

WSAConnectByName

WSAGetLastError

WSAIoctl

WSARecv

WSASend

WSAStartup

Funciones winsock

Referencia de Winsock

WriteFile

bind

closesocket

connect

getsockopt

recv

enviar

sendto

setsockopt

sockaddr