WSAEventSelect
The Windows
Sockets WSAEventSelect function specifies an event object to be
associated with the supplied set of FD_XXX network events.
int WSAEventSelect (
SOCKET s, |
|
WSAEVENT hEventObject, |
|
long lNetworkEvents |
|
); |
|
Parameters
s
[in] A
descriptor identifying the socket.
hEventObject
[in] A handle
identifying the event object to be associated with the supplied set of FD_XXX
network events.
lNetworkEvents
[in] 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.
This function
automatically sets socket s to nonblocking 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 |
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 |
Want to
receive notification of socket group Quality of Service (QOS) changes |
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.
Return Values
The return
value is zero 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 Windows Sockets call which returns
WSAEWOULDBLOCK immediately. For example, the following sequence of operations
is possible:
1. data arrives on socket s; Windows
Sockets sets the WSAEventSelect event object
2. application does some other processing
3. while processing, application issues an ioctlsocket(s,
FIONREAD...) and notices that there is data ready to be read
4. application issues a recv(s,...) to
read the data
5. application eventually waits on event object
specified in WSAEventSelect, which returns immediately indicating that
data is ready to read
6. 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 re-enables 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 |
WSAIoctl with command SIO_GET_GROUP_QOS |
Any call to
the re-enabling routine, even one which fails, results in re-enabling 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 re-enabling
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:
1. Transport provider receives 100 bytes of data
on socket s and causes Windows Sockets DLL to record the FD_READ network
event and set the associated event object.
2. The application issues recv( s, buffptr,
50, 0) to read 50 bytes.
3. The transport provider causes Windows Sockets
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 eventa 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.
If a network
event has already happened when the application calls WSAEventSelect or
when the re-enabling 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, Windows Sockets 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 zero, 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 FIN WAIT or CLOSE WAIT states.
This results from the remote end performing a shutdown on the send side
or a closesocket.
Please note
Windows Sockets 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 specification
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.
Error Codes
WSANOTINITIALISED |
A
successful WSAStartup must occur before using this function. |
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
Windows Sockets 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