WSPAsyncSelect function

The WSPAsyncSelect function requests Windows message-based event notification of network events for a socket.

Syntax

int WSPAsyncSelect(
  _In_  SOCKET       s,
  _In_  HWND         hWnd,
  _In_  unsigned int wMsg,
  _In_  long         lEvent,
  _Out_ LPINT        lpErrno
);

Parameters

  • s [in]
    Descriptor identifying the socket for which event notification is required.

  • hWnd [in]
    Handle identifying the window that should receive a message when a network event occurs.

  • wMsg [in]
    Message to be sent when a network event occurs.

  • lEvent [in]
    Bitmask that specifies a combination of network events in which the Windows Sockets SPI client is interested.

  • lpErrno [out]
    Pointer to the error code.

Return value

The return value is zero if the Winsock SPI client's declaration of interest in the network event set was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error code is available in lpErrno.

Error code Meaning
WSAENETDOWN

The network subsystem has failed.

WSAEINVAL

Indicates that one of the specified parameters was invalid such as the window handle not referring to an existing window, or the specified socket is in an invalid state.

WSAEINPROGRESS

A blocking Winsock call is in progress, or the service provider is still processing a callback function.

WSAENOTSOCK

The descriptor is not a socket.

 

Additional error codes can be set when an application window receives a message. This error code is extracted from the lParam in the reply message using the WSAGETSELECTERROR macro. Possible error codes for each network event are listed in the following table.

Event: FD_CONNECT

Error code Meaning
WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED The attempt to connect was rejected.
WSAENETUNREACH The network cannot be reached from this host at this time.
WSAEFAULT The namelen parameter is invalid.
WSAEINVAL The socket is already bound to an address.
WSAEISCONN The socket is already connected.
WSAEMFILE No more file descriptors are available.
WSAENOBUFS No buffer space is available. The socket cannot be connected.
WSAENOTCONN The socket is not connected.
WSAETIMEDOUT Attempt to connect timed out without establishing a connection.

 

Event: FD_CLOSE

Error code Meaning
WSAENETDOWN The network subsystem failed.
WSAECONNRESET The connection was reset by the remote side.
WSAECONNABORTED The connection was terminated due to a time-out or other failure.

 

Event: FD_ACCEPT

Event: FD_ADDRESS_LIST_CHANGE

Event: FD_GROUP_QOS

Event: FD_OOB

Event: FD_QOS

Event: FD_READ

Event: FD_WRITE

Error code Meaning
WSAENETDOWN The network subsystem failed.

 

Event: FD_ROUTING_INTERFACE_CHANGE

Error code Meaning
WSAENETUNREACH The specified destination is no longer reachable.
WSAENETDOWN The network subsystem failed.

 

Remarks

This function is used to request that the service provider send a Windows message to the client's window hWnd whenever it detects any of the network events specified by the lEvent parameter. The service provider should use the WPUPostMessage function to post the message. The message to be sent is specified by the wMsg parameter. The socket for which notification is required is identified by s.

This function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. See WSPIoctl about how to set the socket back to blocking mode.

The lEvent parameter is constructed by using the bitwise OR operator with any of the values specified in the following list.

Value Meaning
FD_READ Issues notification of readiness for reading.
FD_WRITE Issues notification of readiness for writing.
FD_OOB Issues notification of the arrival of OOB data.
FD_ACCEPT Issues notification of incoming connections.
FD_CONNECT Issues notification of completed connections.
FD_CLOSE Issues notification of socket closure.
FD_QOS Issues notification of socket (QoS) changes.
FD_GROUP_QOS Reserved.
FD_ROUTING_INTERFACE_CHANGE Issues notification of routing interface change for the specified destination.
FD_ADDRESS_ LIST_CHANGE Issues notification of local address list change for the socket's protocol family.

 

Invoking WSPAsyncSelect for a socket cancels any previous WSPAsyncSelect or WSPEventSelect for the same socket. For example, to receive notification for both reading and writing, the Winsock SPI client must call WSPAsyncSelect with both FD_READ and FD_WRITE, as follows:

rc = WSPAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE, &error);

It is not possible to specify different messages for different events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE events will be reported with message wMsg2:

rc = WSPAsyncSelect(s, hWnd, wMsg1, FD_READ, &error);
rc = WSPAsyncSelect(s, hWnd, wMsg2, FD_WRITE, &error);

To cancel all notification (for example, to indicate that the service provider should send no further messages related to network events on the socket) lEvent will be set to zero.

rc = WSPAsyncSelect(s, hWnd, 0, 0, &error);

Since a socket created by WSPAccept has the same properties as the listening socket used to accept it, any WSPAsyncSelect events set for the listening socket apply to the accepted socket. For example, if a listening socket has WSPAsyncSelect events 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 events with the same wMsg value used for messages. If a different wMsg or events are needed, the Winsock SPI client must call WSPAsyncSelect, passing the accepted socket and the new information.

When one of the nominated network events occurs on the specified socket s, the service provider uses WPUPostMessage to send message wMsg to the Winsock SPI client's window hWnd. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code can be any error as defined in Ws2spi.h.

The possible network event codes that may be indicated are shown in the following table.

Value Meaning
FD_READ Socket s is ready for reading.
FD_WRITE Socket s is ready for writing.
FD_OOB OOB data is ready for reading on socket s.
FD_ACCEPT Socket s is ready to accept a new incoming connection.
FD_CONNECT The connection initiated on socket s has completed.
FD_CLOSE The connection identified by socket s has been closed.
FD_QOS The quality of service associated with socket s has changed.
FD_GROUP_QOS Reserved.
FD_ROUTING_INTERFACE_CHANGE The local interface that should be used to send to the specified destination has changed.
FD_ADDRESS_LIST_CHANGE The list of addresses of the socket's protocol family, to which the Winsock SPI client can bind, has changed.

 

Although WSPAsyncSelect can be called with interest in multiple events, the service provider issues the same Windows message for each event.

A Winsock provider will not continually flood a Winsock SPI client with messages for a particular network event. Having successfully posted notification of a particular event to a Winsock SPI client window, no further message(s) for that network event will be posted to the window until the Winsock SPI client makes the function call that implicitly reenables notification of that network event.

Event Reenabling function
FD_READ WSPRecv or WSPRecvFrom.
FD_WRITE WSPSend or WSPSendTo.
FD_OOB WSPRecv or WSPRecvFrom.
FD_ACCEPT WSPAccept unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER.
FD_CONNECT None.
FD_CLOSE None.
FD_QOS WSPIoctl with SIO_GET_QOS.
FD_GROUP_QOS Reserved.
FD_ROUTING_INTERFACE_CHANGE WSPIoctl with command SIO_ROUTING_INTERFACE_CHANGE.
FD_ADDRESS_LIST_CHANGE WSPIoctl with command SIO_ADDRESS_LIST_CHANGE.

 

Any call to the reenabling routine, even one that fails, results in reenabling of message posting for the relevant event.

For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is level-triggered. This means if the reenabling routine is called and the relevant condition is still met after the call, a WSPAsyncSelect message is posted to the Winsock SPI client.

The FD_QOS event is 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 quality of service or the Winsock SPI client renegotiates the quality of service 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 Winsock SPI client has requested the notification by issuing WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the SPI client reissues the IOCTL and another change is detected since the IOCTL has been issued.

If any event has already occurred when the Winsock SPI client calls WSPAsyncSelect or when the reenabling function is called, then an appropriate message is posted. For example, consider the following sequence:

  • An SPI client calls WSPListen.
  • A connect request is received but not yet accepted.
  • The Winsock SPI client calls WSPAsyncSelect specifying that it wants to receive FD_ACCEPT messages for the socket.

Due to the persistence of events, the Winsock service provider posts an FD_ACCEPT message immediately.

The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with WSPConnect (after FD_CONNECT, if also registered) or accepted with WSPAccept, and then after a WSPSend or WSPSendTo fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, a Winsock SPI client can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the Winsock SPI client will be notified that sends are again possible with an FD_WRITE message.

The FD_OOB event is used only when a socket is configured to receive OOB data separately. If the socket is configured to receive OOB data inline, the OOB (expedited) data is treated as normal data and the Winsock SPI client must register an interest in FD_READ events, not FD_OOB events.

The error code in an FD_CLOSE message 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 message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means the FD_CLOSE is posted when the connection goes into the TIME WAIT or CLOSE WAIT states. This results from the remote end performing a WSPShutdown on the send side or a WSPCloseSocket. FD_CLOSE shall only be posted after all data is read from a socket.

In the case of a graceful close, the service provider should only send an FD_CLOSE message to indicate virtual circuit closure after all the received data has been read. It should not send an FD_READ message to indicate this condition.

The FD_QOS message is posted when any member in the flow specification associated with socket s has changed, respectively. The service provider must update the QoS information available to the client through WSPIoctl with SIO_GET_QOS.

The FD_ROUTING_INTERFACE_CHANGE message is posted when the local interface that should be used to reach the destination specified in WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE changes after such IOCTL has been issued.

The FD_ADDRESS_LIST_CHANGE message is posted when the list of addresses to which the Windows Socket 2 SPI client can bind changes after WSPIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.

Here is a summary of events and conditions for each asynchronous notification message:

  • FD_READ:
    • When WSPAsyncSelect is called, if there is data currently available to receive.
    • When data arrives, if FD_READ is not already posted.
    • After WSPRecv or WSPRecvfrom is called (with or without MSG_PEEK), if data is still available to receive.

Note  When WSPSetSockOpt SO_OOBINLINE is enabled, data includes both normal data and OOB data in the instances noted in the preceding.

 

  • FD_WRITE:
    • When WSPAsyncSelect is called, if a WSPSend or WSPSendTo is possible.
    • After WSPConnect or WSPAccept is called, when connection is established.
    • After WSPSend or WSPSendTo fails with WSAEWOULDBLOCK, when WSPSend or WSPSendTo is likely to succeed.
    • After WSPBind on a datagram socket. FD_WRITE may or may not occur at this time (implementation dependent). In any case, a connectionless socket is always writeable immediately after WSPBind.
  • FD_OOB: Only valid when WSPSetSockOpt SO_OOBINLINE is disabled (default).
    • When WSPAsyncSelect is called, if there is OOB data currently available to receive with the MSG_OOB flag.
    • When OOB data arrives, if FD_OOB is not already posted.
    • After WSPRecv or WSPRecvfrom is called with or without MSG_OOB flag, if OOB data is still available to receive.
  • FD_ACCEPT:
    • When WSPAsyncSelect is called, if there is currently a connection request available to accept.
    • When a connection request arrives, if FD_ACCEPT is not already posted.
    • After WSPAccept is called, if there is another connection request available to accept.
  • FD_CONNECT:
    • When WSPAsyncSelect is called, if there is currently a connection established.
    • After WSPConnect is called, when connection is established (even when WSPConnect succeeds immediately, as is typical with a datagram socket, and even when it fails immediately).
    • After WSAJoinLeaf is called, when the join operation completes.
    • After connect, WSAConnect, or WSAJoinLeaf was called with a nonblocking, connection-oriented socket. The initial operation returned with a specific error of WSAEWOULDBLOCK, but the network operation went ahead. Whether the operation eventually succeeds or not, when the outcome has been determined, FD_CONNECT happens. The client should check the error code to determine whether the outcome was a success or failure.
  • FD_CLOSE only valid on connection-oriented sockets (for example, SOC_STREAM):
    • When WSPAsyncSelect is called, if socket connection has been closed.
    • After the remote system initiated a graceful close, when no data is currently available to receive (if data has been received and is waiting to be read when the remote system initiates a graceful close, the FD_CLOSE is not delivered until all pending data has been read).
    • After the local system initiates a graceful close with WSPShutdown and the remote system has responded with End of Data notification (for example, TCP FIN), when no data is currently available to receive.
    • When the remote system terminates connection (for example, sent TCP RST), and lParam will contain the WSAECONNRESET error value. Note  FD_CLOSE is not posted after WSPClosesocket is called.  
  • FD_QOS:
    • When WSPAsyncSelect is called, if the QOS associated with the socket has been changed,
    • After WSPIoctl with SIO_GET_QOS is called, when the QOS is changed.
  • FD_GROUP_QOS: Reserved.
  • FD_ROUTING_INTERFACE_CHANGE:
    • After WSPIoctl with SIO_ROUTING_INTERFACE_CHANGE is called, when the local interface that should be used to reach the destination specified in the IOCTL changes.
  • FD_ADDRESS_LIST_CHANGE:
    • After WSPIoctl with SIO_ADDRESS_LIST_CHANGE is called, when the list of local addresses to which the Windows Socket 2 SPI client can bind changes.

Requirements

Minimum supported client

Windows 2000 Professional [desktop apps only]

Minimum supported server

Windows 2000 Server [desktop apps only]

Header

Ws2spi.h

See also

WSPAccept

WSPCloseSocket

WSPIoctl

WSPRecv

WSPRecvFrom

WSPSelect

WSPSend

WSPSendTo

WSPShutdown