101 WSAEventSelect()
Description Specify an event object to be associated with the supplied set of FD_XXX network events.
#include
int WSAAPI
WSAEventSelect (
IN SOCKET s,
IN WSAEVENT hEventObject,
IN long lNetworkEvents
);
s A descriptor identifying the socket.
hEventObject A handle identifying the event object to be associated with the supplied set of FD_XXX network events.
lNetworkEvents A bitmask which specifies the combination of FD_XXX network events in which the application has interest.
Remarks This function is used to specify an event object, hEventObject, to be associated with the selected FD_XXX network events, lNetworkEvents. The socket for which an event object is specified is identified by s. The event object is set when any of the nominated network events occur.
WSAEventSelect() operates very similarly to WSAAsyncSelect(), the difference being in the actions taken when a nominated network event occurs. Whereas WSAAsyncSelect() causes an application-specified Windows message to be posted, WSAEventSelect() sets the associated event object and records the occurrence of this event in an internal network event record. An application can use WSAWaitForMultipleEvents() to wait or poll on the event object, and use WSAEnumNetworkEvents() to retrieve the contents of the internal network event record and thus determine which of the nominated network events have occurred.
WSAEventSelect() is the only function that causes network activity and errors to be recorded and retrievable through WSAEnumNetworkEvents(). See the descriptions of select() and WSAAsyncSelect() to find out how those functions report network activity and errors.
This function automatically sets socket s to non-blocking mode, regardless of the value of lNetworkEvents. See ioctlsocket()/WSAIoctl() about how to set the socket back to blocking mode.
The lNetworkEvents parameter is constructed by or'ing any of the values specified in the following list.
Value Meaning
FD_READ Want to receive notification of readiness for reading
FD_WRITE Want to receive notification of readiness for writing
FD_OOB Want to receive notification of the arrival of out-of-band data
FD_ACCEPT Want to receive notification of incoming connections
FD_CONNECT Want to receive notification of completed connection or multipoint “join” operation
FD_CLOSE Want to receive notification of socket closure
FD_QOS Want to receive notification of socket Quality of Service (QOS) changes
FD_GROUP_QOS Reserved for future use with socket groups: Want to receive notification of socket group Quality of Service (QOS) changes
FD_ROUTING_INTERFACE_CHANGE
Want to receive notification of routing interface changes for the specified destination
FD_ADDRESS_LIST_CHANGE
Want to receive notification of local address list changes for the socket’s address family
Issuing a WSAEventSelect() for a socket cancels any previous WSAAsyncSelect() or WSAEventSelect() for the same socket and clears the internal network event record. For example, to associate an event object with both reading and writing network events, the application must call WSAEventSelect() with both FD_READ and FD_WRITE, as follows:
rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);
It is not possible to specify different event objects for different network events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE network event will be associated with hEventObject2:
rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad
To cancel the association and selection of network events on a socket, lNetworkEvents should be set to zero, in which case the hEventObject parameter will be ignored.
rc = WSAEventSelect(s, hEventObject, 0);
Closing a socket with closesocket() also cancels the association and selection of network events specified in WSAEventSelect() for the socket. The application, however, still must call WSACloseEvent() to explicitly close the event object and free any resources.
Since an accept()'ed socket has the same properties as the listening socket used to accept it, any WSAEventSelect() association and network events selection set for the listening socket apply to the accepted socket. For example, if a listening socket has WSAEventSelect() association of hEventOject with FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE network events associated with the same hEventObject. If a different hEventObject or network events are desired, the application should call WSAEventSelect(), passing the accepted socket and the desired new information.3
Return Value The return value is 0 if the application's specification of the network events and the associated event object was successful. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError().
As in the case of the select() and WSAAsyncSelect() functions, WSAEventSelect() will frequently be used to determine when a data transfer operation (send() or recv()) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for the possibility that the event object is set and it issues a WinSock call which returns WSAEWOULDBLOCK immediately. For example, the following sequence of operations is possible:
(i) data arrives on socket s; WinSock sets the WSAEventSelect event object
(ii) application does some other processing
(iii) while processing, application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read
(iv) application issues a recv(s,...) to read the data
(v) application eventually waits on event object specified in WSAEventSelect(), which returns immediately indicating that data is ready to read
(vi) application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.
Other sequences are possible.
Having successfully recorded the occurrence of the network event (by setting the corresponding bit in the internal network event record) and signaled the associated event object, no further actions are taken for that network event until the application makes the function call which implicitly reenables the setting of that network event and signaling of the associated event object.
Network Event Re-enabling function
FD_READ recv(), recvfrom(), WSARecv(), or WSARecvFrom()
FD_WRITE send(), sendto(), WSASend(), or WSASendTo()
FD_OOB recv(), recvfrom(), WSARecv(), or WSARecvFrom()
FD_ACCEPT accept() or WSAAccept() unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER
FD_CONNECT NONE
FD_CLOSE NONE
FD_QOS WSAIoctl() with command SIO_GET_QOS
FD_GROUP_QOS Reserved for future use with socket groups: WSAIoctl() with command SIO_GET_GROUP_QOS
FD_ROUTING_INTERFACE_CHANGE
WSAIoctl() with command SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST_CHANGE
WSAIoctl() with command SIO_ADDRESS_LIST_CHANGE
Any call to the reenabling routine, even one which fails, results in reenabling of recording and signaling for the relevant network event and event object, respectively.
For FD_READ, FD_OOB, and FD_ACCEPT network events, network event recording and event object signaling are "level-triggered." This means that if the reenabling routine is called and the relevant network condition is still valid after the call, the network event is recorded and the associated event object is set . This allows an application to be event-driven and not be concerned with the amount of data that arrives at any one time. Consider the following sequence:
(i) transport provider receives 100 bytes of data on socket s and causes WinSock DLL to record the FD_READ network event and set the associated event object.
(ii) The application issues recv( s, buffptr, 50, 0) to read 50 bytes.
(iii) The transport provider causes WinSock DLL to record the FD_READ network event and sets the associated event object again since there is still data to be read.
With these semantics, an application need not read all available data in response to an FD_READ network event --a single recv() in response to each FD_READ network event is appropriate.
The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A message will be posted exactly once when a QOS change occurs. Further messages will not be forthcoming until either the provider detects a further change in QOS or the application renegotiates the QOS for the socket.
The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered “edge triggered” as well. A message will be posted exactly once when a change occurs AFTER the application has request the notification by issuing WSAIoctl() with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the application reissues the IOCTL AND another change is detected since the IOCTL has been issued.
If a network event has already happened when the application calls WSAEventSelect() or when the reenabling function is called, then a network event is recorded and the associated event object is set as appropriate. For example, consider the following sequence: 1) an application calls listen(), 2) a connect request is received but not yet accepted, 3) the application calls WSAEventSelect() specifying that it is interested in the FD_ACCEPT network event for the socket. Due to the persistence of network events, WinSock records the FD_ACCEPT network event and sets the associated event object immediately.
The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with connect()/WSAConnect() or accepted with accept()/WSAAccept(), and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set .
The FD_OOB network event is used only when a socket is configured to receive out-of-band data separately. If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the application should register an interest in, and will get, FD_READ network event, not FD_OOB network event. An application may set or inspect the way in which out-of-band data is to be handled by using setsockopt() or getsockopt() for the SO_OOBINLINE option.
The error code in an FD_CLOSE network event indicates whether the socket close was graceful or abortive. If the error code is 0, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only applies to connection-oriented sockets such as SOCK_STREAM.
The FD_CLOSE network event is recorded when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is recorded when the connection goes into the TIME WAIT or CLOSE WAIT states. This results from the remote end performing a shutdown() on the send side or a closesocket(). FD_CLOSE should only be posted after all data is read from a socket, but an application should check for remaining data upon receipt of FD_CLOSE to avoid any possibility of losing data.
Please note WinSock will record ONLY an FD_CLOSE network event to indicate closure of a virtual circuit. It will NOT record an FD_READ network event to indicate this condition.
The FD_QOS or FD_GROUP_QOS network event is recorded when any field in the flow spec associated with socket s or the socket group that s belongs to has changed, respectively. Applications should use WSAIoctl() with command SIO_GET_QOS or SIO_GET_GROUP_QOS to get the current QOS for socket s or for the socket group s belongs to, respectively.
The FD_ROUTING_INTERFACE_CHANGE nework event is recorded when the local interface that should be used to reach the destination specified in WSAIoctl() with SIO_ROUTING_INTERFACE_CHANGE changes AFTER such IOCTL has been issued.
The FD_ADDRESS_LIST_CHANGE network event is recorded when the list of addresses of socket’s protocol family to which the application can bind changes AFTER WSAIoctl() with SIO_ADDRESS_LIST_CHANGE has been issued.
Error Codes WSANOTINITIALISED A successful WSAStartup() must occur before using this API.
WSAENETDOWN The network subsystem has failed.
WSAEINVAL Indicates that one of the specified parameters was invalid, or the specified socket is in an invalid state.
WSAEINPROGRESS A blocking WinSock 1.1 call is in progress, or the service provider is still processing a callback function).
WSAENOTSOCK The descriptor is not a socket.
See Also WSAAsyncSelect(), WSACloseEvent(), WSACreateEvent(), WSAEnumNetworkEvents(), WSAWaitForMultipleEvents().
Share with your friends: |