current position:Home>[network programming] 9. Event selection wsaeventselect

[network programming] 9. Event selection wsaeventselect

2022-01-26 22:04:54 mb61b856e04bb98


WSAEventSelect The model is similar to WSAAsyncSelect Another useful asynchronous of the model I/O Model . It allows applications to receive event based network events on one or more sockets . ad locum , The main difference is that network events are delivered to an event object handle . Not delivered to a window .

Before we use the event model , Our application first creates an event object for each socket used :

       
WSAEVENT WSACreateEvent(void);
  • 1.


The following is to register the types of network events you are interested in :

       
int WSAEventSelect(
_In_ SOCKET s, // Represents the socket of interest
_In_ WSAEVENT hEventObject,// Specifies the event object to associate with the socket . use WSACreateEvent obtain .
_In_ long lNetworkEvents );// Corresponding to one Bitmask Used to specify a combination of various network event types of interest to the application .
  • 1.
  • 2.
  • 3.
  • 4.


When we use WSACreateEvent Created event , He has two working states and two working modes :

1、 Working state : A letter has been sent signaled and No message nonsignaled.

2、 Working mode : Manual reset manual reset   and   Auto reset auto reset.


At the beginning ,wsacreateevent It's a working state without sending a message , And it is a manual reset mode to create a handle .   But our network event triggers an event object associated with a socket , The working state will change from “ No message ” Turn into “ A letter has been sent ”, Because the event object is Created in a manual reset mode , So after finishing the moth I/O After the request is processed , Our application needs to be responsible for changing the working state to “ No message ”.   To do this, we need a function :


       
BOOL WSAResetEvent(
__in WSAEVENT hEvent
);
  • 1.
  • 2.
  • 3.

The only parameter of the above function is an event handle , Successfully returns TRUE, Failure to return FALSE;


When we finish processing an event object , We're going to call WSACloseEvent function , Release system resources used by event handles :


       
BOOL WSACloseEvent(
__in WSAEVENT hEvent
);
  • 1.
  • 2.
  • 3.


This function also has only one parameter : Event handle . Successfully returns TRUE, Failure to return FALSE;


When one of our sockets is associated with an event handle , The application starts I/O Handle , adopt WSAWaitForMultipleEvents The function waits for a network event to start the working state of the event object handle .( This function is used to wait for one or more event object handles , And enter... After one or all handles specified in advance “ A letter has been sent ” Post state , And return immediately after exceeding a specified event cycle )


       
DWORD WSAWaitForMultipleEvents(
__in DWORD cEvents,// Together with the following parameters, it is determined by WSAEVENT An array of objects , Array cEvents Specifies the number of event objects ,lphEvents Corresponding to a pointer , Used to directly reference the array
__in const WSAEVENT* lphEvents,
__in BOOL fWaitAll,// Specifies how this function waits for objects in the event array
__in DWORD dwTimeout,// Specifies how long this function can wait for a network event to occur at most , Milliseconds , The event specified by the timeout will immediately return the function .
__in BOOL fAlertable// In use WSAEventSelect When modeling , It can be ignored , To set as FALSE. This parameter is mainly used in overlapping I/O In the model .
);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.


Let's take a look at the third parameter fWaitAll.   If you set this parameter to TRUE, So wait lphEvents All event objects contained in the array enter “ A letter has been sent ” The status function returns .   If you set it to FALSE, Then any event object enters “ A letter has been sent ” state , The function will return .

Generally, the application should set this parameter to FALSE, Serve only one socket event at a time .


Fourth parameter dwTimeout It should be noted that try to avoid setting the timeout value to 0, Add events that are not waiting to be processed ,WSAWaitForMultipleEvents Will be returned WSA_WAIT_TIMEOUT.

You set this parameter to :WSAINFINITE( Wait forever ), Then only when a network event sends an event object will the function return .


When WSAWaitForMultipleEvents Receive a network event notification of an event object , Will return a value . Indicate the event object that caused the function to return .   Our application can quote Sent events in the event array , And retrieve the socket corresponding to that event , Determine which socket it is on , What type of network event happened . When referencing an event in an event array , Should use the WSAWaitForMultipleEvents The return value of Subtract the predefined WSA_WAIT_EVENT_0 Get the specific reference value :


       
Index = WSAWaitForMultipleEvents(...);
MyEvent = EventArray[Index - WSA_WAIT_EVENT_0];
  • 1.
  • 2.


When we know the socket that caused the network event , You can call WSAEnumNetworkEvents function , Investigate what types of network events have occurred :


       
int WSAEnumNetworkEvents(
__in SOCKET s,// Corresponding to the socket causing network time
__in WSAEVENT hEventObject,// Optional parameters , Developed an event handle , Corresponding to the event object to be reset . The object of our event was " A letter has been sent “ state , You pass it into , Make it automatically ” No message “ state . If you don't want to use this parameter to reset the event , You can use the function WSAResetEvent.
__out LPWSANETWORKEVENTS lpNetworkEvents// A pointer , Point to WSANETWORKEVENTS structure . Receive the type of network event that occurs on the socket and any error code that may occur .
);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
       
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents; // Specify a value , Corresponds to all network event types that occur on the socket .
int iErrorCode[FD_MAX_EVENTS];// Make an error code array . And lNetworkEvents Events in are linked together , There is a special event index for each network event type , Similar to the name of the event type , Just add a... After the event name ”_BIT" Suffix string is good .
} WSANETWORKEVENTS, *LPWSANETWORKEVENTS;
  • 1.
  • 2.
  • 3.
  • 4.


See the following example :


       
if (NetwordEvents.lNetworkEvents & FD_READ)
{
if (NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
{
printf("FD_READ failed with error %d\n", NetworkEvents.iErrorCode[FD_READ_BIT]);
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.


When finished, right WSANETWORKEVENTS After the processing of events in the structure , Our application should continue to wait for more network events on all available sockets .


Let's take a look at the steps :

1、 Build a socket.

2、 Build a event.

3、 use WSAEventSelect take socket, and event Connect .lNetworkEvents It can be for FD_ACCEPT ,FD_READ ,FD_WRITE,FD_CLOSE wait .

4、 Wait for event handle :index = WSAWaitForMultipleEvents(EventTotal,EventArray,FAlSE,100/*WSA_INFINITE*/,FALSE);

5、 Query network events : int WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents)

6、 use lpNetworkEvents.lNetworkEvents & FD_ACCEPT ,lpNetworkEvents.lNetworkEvents & FD_CLOSE Find each event handler .

copyright notice
author[mb61b856e04bb98],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201262204501149.html

Random recommended