Relying on the downloaded client / server (client / server) program (written by CSocket class), spent more than three hours and lie over the MSDN document, and track the CSocket source sockcore.cpp, a little experience, it is inevitable to be inaccurate and omissions Where:
The client is simple to communicate with the server: The server socket is responsible for listening, answering, receiving, and sending messages, and client socket is just a connection, answering, receiving, and sending messages.
1. There is a certain understanding of the Block (blocking) mechanism for Accept, after calling the server socket, tracking to the source code: while (! Accept (...) {ix (getLastError () == wsaewouldblock // THE Socket is marked as nonblocking and no connection. pumpmed. pumpMessage (fd_accept); else returnaf
An API function that seems to be dead cycles: Accept, Accept, Accept will check the PENDING Connection Queue Queue until a correct
PENDING CONNECTION. Message Pump Functions PumpMessage will ensure that events in the socket do not block, where at least guarantees that the listened FD_ACCEPT event will not block.
2. Typical Problem of actual combat: Why is the server's socket to enter the onaccept message function when the client socket is connected to the server's socket connection.
When Socket is created, the Socket allocates and binds to the corresponding transport service provider according to the descriptor of the socket (individuals think it should be the network transport service process of the Windows operating system), and Socket uses the network to transfer service processes to get some The connection request event of the IP address (client), and then other events such as reception and transmission of the message.
Let's enter the topic below and set the breakpoint to CasyncSocket :: attachhandle:
Socket also calls CasyncSocket :: attachhandle (socket * psocket, casyncsocket * psocket, casyncsocket * psocket, cassocket), Socket instance sentence
The handle and the socket pointer are added to a mapping table variable m_pmapsockethandle of the current module status (Note 1).
Next, in the AttachHandle process, will be a CSocketWnd instance - you can understand that it is a message pool that stores all sockets (Window messages), please check it, I will add a more Socke with a number of s, indicating that multiple people created. Socket will share a message pool CSocketWnd.
When the client socket requires the server's socket connection, the socket is sent to the CSocketWnd of the corresponding event notification message WM_Socket_notify. You may ask how to send the advertisement message to csocketwnd, I have to know the csocketwnd pointer? The answer is that the pointer (actually the window handle) has been saved in the M_HSocketWindow variable in the current thread state, take it! CSocketWnd Receives the message function after receiving the event notification message: (Try: Try to set breakpoints in OnsetNotify) LRESULT CSOCKETWND: : OnsetNotify (WParam WPARAM, LPARAM LPARAM) {CSocket :: AuxqueueAdd (WM_Socket_notify, WParam, LPARAM); CSocket :: Processauxqueue (); Return 0L;}
Is a little strange code? The CSocketWnd class is a friend class as a CSocket class, which means that it can access the protection and private member functions and variables in the CSocket class, AuxqueueAdd and Processauxqueue are
The static member function of the CSocket class, understand! Don't you understand? Look for this C book to see the friend's way! PS: Message Parameters WPARAM is the handle of the socket, LParam is an event of Socket. OK! Stick, I really have a little dizzy, but I haven't finished, let's go ON! ProcessAuxqueue is a function of the substantial handle of the Socket Notice message, there is such a code in this function:
CasyncSocket * psocket = CasyncSocket :: LookupHandle ((socket) wparam, true);
In fact, the Socket Pointer psocket is obtained by the Socket handle to send event notification messages: Find from m_pmapsockethandle!
Finally, WsagetSelectEvent (LPARAM) takes out the event type, and determines the event type in a simple Switch statement and invoke the event handler. Here, the event type is fd_accept, of course, call psocket-> onaccept!
Note:
1. Current module status: A structure for saving the current thread and module status can be obtained by AFXGetThreadModule (). AFX_MODULE_THREAD_STATE is redefined in CSocket to _afx_sock_thread_state.