Windows* Sockets 2 Application Programming Interface An Interface for Transparent Network Programming Under Microsoft Windowstm revision 2 August 7, 1997



Download 1.64 Mb.
Page25/49
Date31.07.2017
Size1.64 Mb.
#24975
1   ...   21   22   23   24   25   26   27   28   ...   49

92 WSAAsyncSelect()


Description Request Windows message-based notification of network events for a socket.
#include < winsock2.h >
int WSAAPI
WSAAsyncSelect (
IN SOCKET
s,
IN HWND
hWnd,
IN unsigned int
wMsg,
IN long
lEvent
);

s A descriptor identifying the socket for which event notification is required.
hWnd A handle identifying the window which should receive a message when a network event occurs.
wMsg The message to be received when a network event occurs.
lEvent A bitmask which specifies a combination of network events in which the application is interested.
Remarks This function is used to request that the WinSock DLL should send a message to the window hWnd whenever it detects any of the network events specified by the lEvent parameter. The message which should 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 non-blocking mode, regardless of the value of lEvent. See ioctlsocket() about how to set the non-blocking socket back to blocking mode.
The lEvent 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(s)

FD_ADDRESS_LIST_CHANGE

Want to receive notification of local address list changes for the socket’s protocol family

Issuing a WSAAsyncSelect() for a socket cancels any previous WSAAsyncSelect() or WSAEventSelect() for the same socket. For example, to receive notification for both reading and writing, the application must call WSAAsyncSelect() with both FD_READ and FD_WRITE, as follows:


rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);
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 = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);

rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);


To cancel all notification  i.e., to indicate that WinSock should send no further messages related to network events on the socket  lEvent should be set to zero.
rc = WSAAsyncSelect(s, hWnd, 0, 0);
Although in this instance WSAAsyncSelect() immediately disables event message posting for the socket, it is possible that messages may be waiting in the application's message queue. The application must therefore be prepared to receive network event messages even after cancellation. Closing a socket with closesocket() also cancels WSAAsyncSelect() message sending, but the same caveat about messages in the queue prior to the closesocket() still applies.
Since an accept()'ed socket has the same properties as the listening socket used to accept it, any WSAAsyncSelect() events set for the listening socket apply to the accepted socket. For example, if a listening socket has WSAAsyncSelect() 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 desired, the application should call WSAAsyncSelect(), passing the accepted socket and the desired new information.2
When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam argument 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 be any error as defined in winsock2.h. Note: Upon receipt of an event notification message the WSAGetLastError() function cannot be used to check the error value, because the error value returned may differ from the value in the high word of lParam.
The error and event codes may be extracted from the lParam using the macros WSAGETSELECTERROR and WSAGETSELECTEVENT, defined in winsock2.h as:
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)

#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)


The use of these macros will maximize the portability of the source code for the application.
The possible network event codes which may be returned are as follows:
Value Meaning

FD_READ Socket s ready for reading

FD_WRITE Socket s ready for writing

FD_OOB Out-of-band data ready for reading on socket s

FD_ACCEPT Socket s ready for accepting a new incoming connection

FD_CONNECT Connection or multipoint “join” operation initiated on socket s completed

FD_CLOSE Connection identified by socket s has been closed

FD_QOS Quality of Service associated with socket s has changed

FD_GROUP_QOS Reserved for future use with socket groups: Quality of Service associated with the socket group to which s belongs has changed

FD_ROUTING_INTERFACE_CHANGE

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 application client can bind has changed

Return Value The return value is 0 if the application's declaration of interest in the network event set was successful. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError().
Comments Although WSAAsyncSelect() can be called with interest in multiple events, the application window will receive a single message for each network event.
As in the case of the select() function, WSAAsyncSelect() 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 it may receive a message and issue a Winsock 2 call which returns WSAEWOULDBLOCK immediately. For example, the following sequence of events is possible:
(i) data arrives on socket s; Winsock 2 posts WSAAsyncSelect message

(ii) application processes some other message

(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 loops to process next message, eventually reaching the WSAAsyncSelect message indicating that data is ready to read

(vi) application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.


Other sequences are possible.
The Winsock DLL will not continually flood an application with messages for a particular network event. Having successfully posted notification of a particular event to an application window, no further message(s) for that network event will be posted to the application window until the application makes the function call which implicitly reenables notification of that network event.
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 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 message posting for the relevant event.
For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggered." This means that if the reenabling routine is called and the relevant condition is still met after the call, a WSAAsyncSelect() message is posted to the application. 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) network transport stack receives 100 bytes of data on socket s and causes Winsock 2 to post an FD_READ message.

(ii) The application issues recv( s, buffptr, 50, 0) to read 50 bytes.



(iii) another FD_READ message is posted 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 message--a single recv() in response to each FD_READ message is appropriate. If an application issues multiple recv() calls in response to a single FD_READ, it may receive multiple FD_READ messages. Such an application may wish to disable FD_READ messages before starting the recv() calls by calling WSAAsyncSelect() with the FD_READ event not set.
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 message is posted 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 message is posted when the list of addresses to which the application can bind changes AFTER WSAIoctl() with SIO_ADDRESS_LIST_CHANGE has been issued.
If any event has already happened when the application calls WSAAsyncSelect() or when the reenabling function is called, then a message is posted 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 WSAAsyncSelect() specifying that it wants to receive FD_ACCEPT messages for the socket. Due to the persistence of events, Winsock 2 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 connect()/WSAConnect() (after FD_CONNECT, if also registered) or accepted with accept()/WSAAccept(), and then after a send operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application 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 application 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 out-of-band data separately (see section 3.5. Out-Of-Band data for a discussion of this topic). 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 receive, FD_READ events, not FD_OOB events. 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 message 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 message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that 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 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 your application will receive ONLY an FD_CLOSE message to indicate closure of a virtual circuit, and only when all the received data has been read if this is a graceful close. It will NOT receive an FD_READ message to indicate this condition.
The FD_QOS or FD_GROUP_QOS message is posted 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 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.
Here is a summary of events and conditions for each asynchronous notification message:
FD_READ:

1) when WSAAsyncSelect() called, if there is data currently available to receive,

2) when data arrives, if FD_READ not already posted,

3) after recv() or recvfrom() called (with or without MSG_PEEK), if data is still available to receive.

(Note: when setsockopt() SO_OOBINLINE is enabled "data" includes both normal data and out-of-band (OOB) data in the instances noted above.
FD_WRITE:

1) when WSAAsyncSelect() called, if a send() or sendto() is possible

2) after connect() or accept() called, when connection established

3) after send() or sendto() fail with WSAEWOULDBLOCK, when send() or sendto() are likely to succeed,

4) after bind() on a connectionless socket. FD_WRITE may or may not occur at this time (implementation dependent). In any case, a connectionless socket is always writeable immediately after bind().
FD_OOB: Only valid when setsockopt() SO_OOBINLINE Is

disabled (default).

1) when WSAAsyncSelect() called, if there is OOB data currently available to receive with the MSG_OOB flag,

2) when OOB data arrives, if FD_OOB not already posted,

3) after recv() or recvfrom() called with or without MSG_OOB flag, if OOB data is still available to receive.
FD_ACCEPT:

1) when WSAAsyncSelect() called, if there is currently a connection request available to accept,

2) when a connection request arrives, if FD_ACCEPT not already posted,

3) after accept() called, if there is another connection request available to accept.


FD_CONNECT:

1) when WSAAsyncSelect() called, if there is currently a connection established,



  1. after connect() called, when connection is established (even when connect() succeeds immediately, as is typical with a datagram socket, and even when it fails immediately).

  2. after WSAJoinLeaf() called, when join operation completes.

  3. after connect(), WSAConnect(), or WSAJoinLeaf() was called with a non-blocking, 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 success or failure.

FD_CLOSE: Only valid on connection-oriented sockets (e.g. SOCK_STREAM)

1) when WSAAsyncSelect() called, if socket connection has been closed,

2) after remote system initiated graceful close, when no data currently available to receive (note: 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),

3) after local system initiates graceful close with shutdown() and remote system has responded with "End of Data" notification (e.g. TCP FIN), when no data currently available to receive,

4) when remote system aborts connection (e.g. sent TCP RST), and lParam will contain WSAECONNRESET error value.

Note: FD_CLOSE is not posted after closesocket() is called.
FD_QOS:

1) when WSAAsyncSelect() called, if the QOS associated with the socket has been changed,

2) after WSAIoctl() with SIO_GET_QOS called, when the QOS is changed.
FD_GROUP_QOS:
Reserved for future use with socket groups:

1) when WSAAsyncSelect() called, if the group QOS associated with the socket has been changed,

2) after WSAIoctl() with SIO_GET_GROUP_QOS called, when the group QOS is changed.
FD_ROUTING_INTERFACE_CHANGE:

1) after WSAIoctl() with SIO_ROUTING_INTERFACE_CHANGE called, when the local interface that should be used to reach the destination specified in the IOCTL changes.


FD_ADDRESS_LIST_CHANGE:

1) after WSAIoctl() with SIO_ADDRESS_LIST_CHANGE called, when the list of local addresses to which the application can bind changes.


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 such as the window handle not referring to an existing window, 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.
Additional error codes may 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:

Event: FD_CONNECT

Error Code Meaning

WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.


WSAECONNREFUSED The attempt to connect was forcefully rejected.
WSAENETUNREACH The network can't be reached from this host at this time.
WSAEFAULT The namelen argument is incorrect.
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 has failed.


WSAECONNRESET The connection was reset by the remote side.
WSAECONNABORTED The connection was aborted due to timeout or other failure.
Event: FD_READ

Event: FD_WRITE

Event: FD_OOB

Event: FD_ACCEPT

Event: FD_QOS

Event: FD_GROUP_QOS

Event: FD_ADDRESS_LIST_CHANGE

Error Code Meaning

WSAENETDOWN The network subsystem has failed.



Event: FD_ROUTING_INTERFACE_CHANGE

Error Code Meaning

WSAENETUNREACH The specified destination is no longer reachable

WSAENETDOWN The network subsystem has failed.




See Also select(), WSAEventSelect()

Download 1.64 Mb.

Share with your friends:
1   ...   21   22   23   24   25   26   27   28   ...   49




The database is protected by copyright ©ininet.org 2024
send message

    Main page