1. Why do we understand this now?
Do not know this socket overlap IO this model is not the basis of socket IO completion port, but I feel that learning this again to learn the socket IO completion port is more advantageous.
This scoket overlapping IO I remember seeing it several times before and I didn't understand it. Part of the reason is that I haven't been able to write the code statically, and more importantly, it's hard to understand that the sockets overlap their structure parameters and pass parameters. I'll explain these data structures and parameters below
2. Initial knowledge of the WSARECV function
int WSARecv ( socket S,//Socket //structure array to receive the message . When the receive IO operation is finished, the received content is inside this // How many wsabuf lpdword LPNUMBEROFBYTESRECVD,// The number of bytes received lpdword lpflags, lpwsaoverlapped lpoverlapped,// OVERLAPPED structure pointer lpwsaoverlapped_completion_routine lpcompletionroutine// not in this );
Lpbuffers parameter: This is a wsabuf array, meaning that this function can receive more than one character buffer, but we generally use one to be enough. Receive multiple I haven't been able to test
Dwbuffercount parameter: Refers to the number of arrays of the previous parameter
lpoverlapped parameter: This parameter is a pointer to the Overlappad struct, which is populated by the system when the IO operation is complete. This structure can also be obtained by WSAGetOverlappedResult when the IO operation is completed
return value:
0: No error occurred, IO operation completed immediately
Socket_error: Error occurred
If it is socket_error and wsagetlasterror () = = Wsa_io_pending This indicates that the operation has been committed. Most of the asynchronous operations are like this.
3. When to receive the message and then take out the message
When the exception operation is complete, the overlapped Hevent event is triggered. At this point the overlapped Internalhigh represents the number of bytes accepted. Internal represents the error code. The content of the message is the Lpbuffers parameter that you passed in when you called WSARecv.
4. Code organization
Take the service side as an example
The first few parameters that pass into the WSARECV must be associated with a socket. And these parameters after the asynchronous call is completed, but will be used later (in waitformutiobjects), and each socket has a different event to identify which client is the message. So construct a overlapped structure for each client socket. For example, I test the code in each client has such a structure, and when the accept to indicate that there is a new socket connection, you have to generate such a structure, when the client dropped the line, you have to delete such a struct
Here is the structure:
struct cclientinfo{public: cclientinfo () { ZeroMemory (&m_ol,sizeof (M_ol)); ZeroMemory (M_szbuf,N); = wsacreateevent (); } ~cclientinfo () { wsacloseevent (m_ol.hevent); } wsaoverlapped M_ol; SOCKET Ssocket; CString strIp; U_short nport; CString Getshowtext (); Char m_szbuf[[];};
Here are two functions, one when the client is connected, and the other is when the client disconnects
Cclientinfo * cserverdlg::onsocketconnected (SOCKET sclientsocket,sockaddr_in *saclient) {U_short Uport= Ntohs (((sockaddr_in *) saclient)sin_port); CString strIp= CA2T (Inet_ntoa ((sockaddr_in *) saclient)sin_addr)); Cclientinfo* Pclientinfo =NewCclientinfo; Pclientinfo->nport =Uport; Pclientinfo->strip =strIp; Pclientinfo->ssocket =Sclientsocket; Lockclientarray (); M_clientarray.add (Pclientinfo); intnindexinserted = m_clientlistbox.addstring (pclientinfo->Getshowtext ()); M_clientlistbox.setitemdata (Nindexinserted,pclientinfo-ssocket); Unlockclientarray (); returnPclientinfo;}voidCserverdlg::onsocketdisconnect (SOCKET aclientsocket) {Lockclientarray (); for(inti =0; I<m_clientarray.getcount (); i++) {Cclientinfo* Pclientinfo =M_clientarray.getat (i); if(Pclientinfo->ssocket = =aclientsocket) {m_clientlistbox.deletestring (m_clientlistbox.findstring (0,pclientinfo->Getshowtext ())); DeletePclientinfo; M_clientarray.removeat (i); Break; }} unlockclientarray ();}
5. No test content and questions
If the WSARECV call two times what would be the case, there is no effect.
I do not use asynchronous AcceptEx, feel this function is asynchronous, function is not small, later if necessary, then learn it
Send the time did not use WSASend, later study
Socket overlap IO