Función WSAEventSelect (winsock2.h)

La función WSAEventSelect especifica un objeto de evento que se va a asociar al conjunto especificado de eventos de red de FD_XXX.

Sintaxis

int WSAAPI WSAEventSelect(
  [in] SOCKET   s,
  [in] WSAEVENT hEventObject,
  [in] long     lNetworkEvents
);

Parámetros

[in] s

Descriptor que identifica el socket.

[in] hEventObject

Identificador que identifica el objeto de evento que se va a asociar al conjunto especificado de eventos de red de FD_XXX.

[in] lNetworkEvents

Máscara de bits que especifica la combinación de FD_XXX eventos de red en los que la aplicación tiene interés.

Valor devuelto

El valor devuelto es cero si la especificación de la aplicación de los eventos de red y el objeto de evento asociado se realizó correctamente. De lo contrario, se devuelve el valor SOCKET_ERROR y se puede recuperar un número de error específico llamando a WSAGetLastError.

Como en el caso de las funciones select y WSAAsyncSelect , WSAEventSelect se usará con frecuencia para determinar cuándo se puede emitir una operación de transferencia de datos (envío o recv) con la expectativa de éxito inmediato. Sin embargo, una aplicación sólida debe estar preparada para la posibilidad de que se establezca el objeto de evento y emite una llamada de Windows Sockets que devuelve WSAEWOULDBLOCK inmediatamente. Por ejemplo, es posible la siguiente secuencia de operaciones:

  • Los datos llegan al socket s; Windows Sockets establece el objeto de evento WSAEventSelect .
  • La aplicación realiza otro procesamiento.
  • Durante el procesamiento, la aplicación emite un ioctlsocket(s, FIONREAD...) y observa que hay datos listos para leerse.
  • La aplicación emite un recv(s,...) para leer los datos.
  • La aplicación finalmente espera en el objeto de evento especificado en WSAEventSelect, que devuelve inmediatamente que indica que los datos están listos para leerse.
  • La aplicación emite recv(s,...), que produce el error WSAEWOULDBLOCK.
Después de registrar correctamente la aparición del evento de red (estableciendo el bit correspondiente en el registro de eventos de red interno) y señalizado el objeto de evento asociado, no se realizan más acciones para ese evento de red hasta que la aplicación realiza la llamada de función que vuelve a habilitar implícitamente la configuración de ese evento de red y la señalización del objeto de evento asociado.
Evento de red Volver a habilitar la función
FD_READ
La función recv, recvfrom, WSARecv, WSARecvEx o WSARecvFrom .
FD_WRITE
Función send, sendto, WSASend o WSASendTo .
FD_OOB
La función recv, recvfrom, WSARecv, WSARecvEx o WSARecvFrom .
FD_ACCEPT
La función accept, AcceptEx o WSAAccept a menos que el código de error devuelto sea WSATRY_AGAIN que indique que la función de condición devolvió CF_DEFER.
FD_CONNECT
Ninguno.
FD_CLOSE
Ninguno.
FD_QOS
Función WSAIoctl con SIO_GET_QOS de comandos.
FD_GROUP_QOS
Reservado.
FD_ROUTING_ INTERFACE_CHANGE
Función WSAIoctl con SIO_ROUTING_INTERFACE_CHANGE de comandos.
FD_ADDRESS_ LIST_CHANGE
Función WSAIoctl con SIO_ADDRESS_LIST_CHANGE de comandos.
 

Cualquier llamada a la rutina de reen habilitación, incluso una que produzca un error, da como resultado volver a habilitar la grabación y señalización para el evento de red y el objeto de evento pertinentes.

Para FD_READ, FD_OOB y eventos de red FD_ACCEPT, la grabación de eventos de red y la señalización de objetos de eventos se desencadenan a nivel. Esto significa que si se llama a la rutina de volver a habilitar y la condición de red pertinente sigue siendo válida después de la llamada, se registra el evento de red y se establece el objeto de evento asociado. Esto permite que una aplicación se controle por eventos y no se preocupe por la cantidad de datos que llegan en cualquier momento. Considere la siguiente secuencia:

  1. El proveedor de transporte recibe 100 bytes de datos en sockets y hace que WS2_32.DLL registre el evento de red FD_READ y establezca el objeto de evento asociado.
  2. La aplicación emite recv(s, buffptr, 50, 0) para leer 50 bytes.
  3. El proveedor de transporte hace que WS2_32.DLL registre el evento de red FD_READ y vuelva a establecer el objeto de evento asociado, ya que todavía hay datos que se van a leer.
Con esta semántica, una aplicación no necesita leer todos los datos disponibles en respuesta a un evento de red de FD_READ, una única repetición en respuesta a cada evento de red FD_READ es adecuado.

El evento FD_QOS se considera desencadenado por el borde. Un mensaje se publicará exactamente una vez cuando se produzca un cambio de calidad de servicio. Los mensajes adicionales no se publicarán hasta que el proveedor detecte un cambio adicional en la calidad del servicio o la aplicación renegocia la calidad del servicio para el socket.

Los eventos FD_ROUTING_INTERFACE_CHANGE y FD_ADDRESS_LIST_CHANGE también se consideran desencadenados en el perímetro. Un mensaje se publicará exactamente una vez cuando se produzca un cambio después de que la aplicación haya solicitado la notificación emitiendo WSAIoctl con SIO_ROUTING_INTERFACE_CHANGE o SIO_ADDRESS_LIST_CHANGE correspondientemente. Otros mensajes no estarán disponibles hasta que la aplicación vuelva a emitir el IOCTL y se detecte otro cambio, ya que se ha emitido el IOCTL.

Si ya se ha producido un evento de red cuando la aplicación llama a WSAEventSelect o cuando se llama a la función de reen habilitación, se registra un evento de red y el objeto de evento asociado se establece según corresponda. Considere, por ejemplo, la secuencia siguiente:

  1. Una aplicación llama a escucha.
  2. Se recibe una solicitud de conexión, pero aún no se acepta.
  3. La aplicación llama a WSAEventSelect especificando que está interesado en el evento de red FD_ACCEPT para el socket. Debido a la persistencia de eventos de red, Windows Sockets registra el evento de red FD_ACCEPT y establece el objeto de evento asociado inmediatamente.
El evento de red FD_WRITE se controla ligeramente de forma diferente. Un evento de red FD_WRITE se registra cuando un socket se conecta por primera vez con una llamada a la función connect, ConnectEx, WSAConnect, WSAConnectByList o WSAConnectByName o cuando se acepta un socket con la función accept, AcceptEx o WSAAccept y, después de que se produzca un error de envío con WSAEWOULDBLOCK y el espacio de búfer esté disponible. Por lo tanto, una aplicación puede suponer que los envíos son posibles a partir de la primera configuración de eventos de red FD_WRITE y duraderas hasta que un envío devuelve WSAEWOULDBLOCK. Después de este error, la aplicación averiguará que los envíos son posibles de nuevo cuando se registra un evento de red FD_WRITE y se establece el objeto de evento asociado.

El evento de red FD_OOB solo se usa cuando un socket está configurado para recibir datos OOB por separado. Si el socket está configurado para recibir datos OOB insertados, los datos de OOB (acelerados) se tratan como datos normales y la aplicación debe registrar un interés y obtendrá FD_READ evento de red, no FD_OOB evento de red. Una aplicación puede establecer o inspeccionar la forma en que se van a controlar los datos OOB mediante setsockopt o getockopt para la opción SO_OOBINLINE.

El código de error de un evento de red FD_CLOSE indica si el cierre del socket era correcto o anulativo. Si el código de error es cero, el cierre fue correcto; Si el código de error es WSAECONNRESET, se restablece el circuito virtual del socket. Esto solo se aplica a sockets orientados a la conexión, como SOCK_STREAM.

El evento de red FD_CLOSE se registra cuando se recibe una indicación de cierre para el circuito virtual correspondiente al socket. En términos TCP, esto significa que el FD_CLOSE se registra cuando la conexión entra en los estados TIME WAIT o CLOSE WAIT. Esto resulta de que el extremo remoto realiza un apagado en el lado de envío o un closesocket. FD_CLOSE publicar después de leer todos los datos de un socket. Una aplicación debe comprobar los datos restantes tras la recepción de FD_CLOSE para evitar la posibilidad de perder datos. Para obtener más información, consulte la sección sobre Cierre correcto, Opciones de persistencia y Cierre de socket y la función de apagado .

Tenga en cuenta que Windows Sockets registrará solo un evento de red FD_CLOSE para indicar el cierre de un circuito virtual. No registrará un evento de red FD_READ para indicar esta condición.

El FD_QOS o FD_GROUP_QOS evento de red se registra cuando cualquier parámetro de la especificación de flujo asociada a sockets. Las aplicaciones deben usar WSAIoctl con el comando SIO_GET_QOS para obtener la calidad actual del servicio para sockets.

El evento de red FD_ROUTING_INTERFACE_CHANGE se registra cuando la interfaz local que se debe usar para llegar al destino especificado en WSAIoctl con SIO_ROUTING_INTERFACE_CHANGE cambios después de que se haya emitido dicho IOCTL.

El evento de red FD_ADDRESS_LIST_CHANGE se registra cuando se ha emitido la lista de direcciones de la familia de protocolos para el socket al que la aplicación puede enlazar los cambios después de que se haya emitido WSAIoctl con SIO_ADDRESS_LIST_CHANGE .

Código de error Significado
WSANOTINITIALISED Debe producirse una llamada de WSAStartup correcta antes de usar esta función.
WSAENETDOWN Error en el subsistema de red.
WSAEINVAL Uno de los parámetros especificados no era válido o el socket especificado está en un estado no válido.
WSAEINPROGRESS Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada.
WSAENOTSOCK El descriptor no es un socket.

Comentarios

La función WSAEventSelect se usa para especificar un objeto de evento, hEventObject, que se asociará con los eventos de red de FD_XXX seleccionados, lNetworkEvents. El socket para el que se especifica un objeto de evento se identifica mediante el parámetro s . El objeto de evento se establece cuando se produce cualquiera de los eventos de red designados.

La función WSAEventSelect funciona de forma muy similar a WSAAsyncSelect, siendo la diferencia las acciones realizadas cuando se produce un evento de red designado. La función WSAAsyncSelect hace que se publique un mensaje de Windows especificado por la aplicación. WSAEventSelect establece el objeto de evento asociado y registra la aparición de este evento en un registro de eventos de red interno. Una aplicación puede usar WSAWaitForMultipleEvents para esperar o sondear en el objeto de evento y usar WSAEnumNetworkEvents para recuperar el contenido del registro de eventos de red interno y, por tanto, determinar cuál de los eventos de red designados se ha producido.

La manera adecuada de restablecer el estado de un objeto de evento usado con la función WSAEventSelect es pasar el identificador del objeto de evento a la función WSAEnumNetworkEvents en el parámetro hEventObject . Esto restablecerá el objeto de evento y ajustará el estado de los eventos FD activos en el socket de forma atómica.

WSAEventSelect es la única función que hace que la actividad de red y los errores se registren y recuperen a través de WSAEnumNetworkEvents. Consulte las descripciones de select y WSAAsyncSelect para averiguar cómo esas funciones notifican la actividad y los errores de red.

La función WSAEventSelect establece automáticamente el socket s en modo sin bloqueo, independientemente del valor de lNetworkEvents. Para volver al modo de bloqueo del socket, primero es necesario borrar el registro de eventos asociado a sockets a través de una llamada a WSAEventSelect con lNetworkEvents establecido en cero y el parámetro hEventObject establecido en NULL. A continuación, puede llamar a ioctlsocket o WSAIoctl para volver a establecer el socket en modo de bloqueo.

El parámetro lNetworkEvents se construye mediante el operador OR bit a bit con cualquiera de los valores especificados en la lista siguiente.

Valor Significado
FD_READ Quiere recibir una notificación de preparación para la lectura.
FD_WRITE Quiere recibir notificaciones de preparación para escribir.
FD_OOB Quiere recibir una notificación de la llegada de datos de OOB.
FD_ACCEPT Quiere recibir una notificación de las conexiones entrantes.
FD_CONNECT Quiere recibir una notificación de la conexión completada o de la operación de combinación multipunto.
FD_CLOSE Quiere recibir una notificación de cierre de socket.
FD_QOS Quiere recibir la notificación del socket (cambios de QoS.
FD_GROUP_QOS Reservado para uso futuro con grupos de sockets. Quiere recibir una notificación de los cambios de QoS del grupo de sockets.
FD_ROUTING_ INTERFACE_CHANGE Quiere recibir la notificación de los cambios de la interfaz de enrutamiento para el destino especificado.
FD_ADDRESS_ LIST_CHANGE Quiere recibir la notificación de los cambios de la lista de direcciones locales para la familia de direcciones del socket.
 

La emisión de un WSAEventSelect para un socket cancela cualquier WSAAsyncSelect o WSAEventSelect anterior para el mismo socket y borra el registro de eventos de red interno. Por ejemplo, para asociar un objeto de evento con eventos de red de lectura y escritura, la aplicación debe llamar a WSAEventSelect con FD_READ y FD_WRITE, como se indica a continuación:

rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);

No es posible especificar objetos de evento diferentes para diferentes eventos de red. El código siguiente no funcionará; la segunda llamada cancelará los efectos del primero y solo se asociará el evento de red FD_WRITE con hEventObject2:

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad

Para cancelar la asociación y selección de eventos de red en un socket, lNetworkEvents debe establecerse en cero, en cuyo caso se omitirá el parámetro hEventObject .

rc = WSAEventSelect(s, hEventObject, 0);

Al cerrar un socket con closesocket también se cancela la asociación y selección de eventos de red especificados en WSAEventSelect para el socket. Sin embargo, la aplicación todavía debe llamar a WSACloseEvent para cerrar explícitamente el objeto de evento y liberar todos los recursos.

El socket creado cuando se llama a la función accept tiene las mismas propiedades que el socket de escucha usado para aceptarlo. Cualquier selección de eventos de red y asociación WSAEventSelect establecida para el socket de escucha se aplica al socket aceptado. Por ejemplo, si un socket de escucha tiene la asociación WSAEventSelect de hEventObject con FD_ACCEPT, FD_READ y FD_WRITE, cualquier socket aceptado en ese socket de escucha también tendrá FD_ACCEPT, FD_READ y FD_WRITE eventos de red asociados con el mismo hEventObject. Si se desea otro hEventObject o eventos de red, la aplicación debe llamar a WSAEventSelect, pasando el socket aceptado y la nueva información deseada.

Código de ejemplo

En el ejemplo siguiente se muestra el uso de la función WSAEventSelect .
//-------------------------
// Declare and initialize variables
SOCKET ListenSocket;
WSAEVENT NewEvent;
sockaddr_in InetAddr;

//-------------------------
// Initialize listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//-------------------------
// Bind listening socket
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InetAddr.sin_port = htons(27015);

bind (ListenSocket, (SOCKADDR *) &InetAddr, sizeof(InetAddr));

//-------------------------
// Create new event
NewEvent = WSACreateEvent();

//-------------------------
// Associate event types FD_ACCEPT and FD_CLOSE
// with the listening socket and NewEvent
WSAEventSelect( ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);

//----------------------
// Listen for incoming connection requests 
// on the created socket
if (listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR)
    printf("Error listening on socket.\n");

printf("Listening on socket...\n");

// Need an event handler added to handle connection requests



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 winsock2.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

WSAAsyncSelect

WSACloseEvent

WSACreateEvent

WSAEnumNetworkEvents

WSAWaitForMultipleEvents

Funciones winsock

Referencia de Winsock

shutdown