Note: This article is reproduced from "starlight's weblog" http://blog.9cbs.net/yjgx007/archive/2005/01/03/237955.aspx
Suitable for primary intermediate readers
Sometimes, spend a few hours to read, debug, track outstanding source programs, able to master certain technical critical points and essence faster. Of course, the premise is that these technologies have roughly a understanding.
I passed several CSocket classes and programs that use CLIENT / Server (client / server) network chat and transfer files (see: Source Reference), tracking in the CSocket class in the process of debuging these programs Core source sockcore.cpp, the running mechanism for the CSocket class can be described as a list, and the writing of the Socket program in the blocking and non-blocking mode is also a slight experience.
Please read this article, please pay attention to:
• The blocked and non-blocking concepts here are only applicable to the Server side Socket program.
• Socket means a socket, which is different from the socket, please pay attention to the case of the initial letter.
Description: The client is simple to communicate with the server: The server socket is responsible for listening, responding, receiving, and sending messages, while client sockets are just connected, responding, receiving, and sending messages. Also, if you are not very well understood by writing a CSocket class, please query (see: Refer to books and online help).
Before this, it is necessary to tell: Network Transport Service Provider, WS2_32.dll, Socket Event, and Socket Window.
1. Network Transport Service Provider (Network Transmission Service Process), Socket Event, Socket Window
The TRANSPORT service provider is existing in the form of a DLL, and is loaded by the service process svchost.exe when the Windows operating system starts. When Socket is created, call the API function socket (in WS2_32.dll), the Socket function passes three parameters: address family, socket type (Note 2) and protocol, these three parameters determine which one Types of network transport service providers launch network transport service functions. All network communication is complete by the network transmission service provider, here to refer to the network transmission service process more helpful, because the previous article has been mentioned by the network transport service provider is from the SVCHOST.EXE service process Loaded.
The figure below describes the interface hierarchical relationship between network applications, csocket (wsock32.dll), socket api (ws2_32.dll), and network transfer service processes:
When the Client side socket communicates with the Server side Socket, both ends trigger a socket event:
Here is only two Socket events:
FD_CONNECT: Connecting events, usually triggered when the CLIENT Socket calls the socket API function Connect, which occurs in the Client side.
FD_ACCEPT: The connection event being introduced, usually the Server side Socket is triggered when the SOCKET connection is received, and this event occurs at the Server side.
Network Transfer Service Process Save the Socket event to the Socket event queue.
In addition, the network transmission service process also sends a message WM_Socket_notify to the Socket Window, notifying the Socket event generation, see the following detailed description of Socket Window:
After calling the csocket :: Create function, the socket is created. CasyncSocket :: attachhandle (socket hsocket, casocket). The function of this function is:
a. Adding a Socket Equivation and Socket Pointer to a mapping table variable m_pmapsockethandle of the current module status (Note 1).
b. During the attachhandle process, a CSocketWnd instance (based on CWnd derived), here to call this instance as socket window, further understanding that it is a message pool for all sockets (Window message), please see, here Socket After adding a S, multiple sockets that are created will share a message pool.
c. When the Client side socket communicates with the Server end, the network transmission service process sends a message WM_Socket_notify to the Socket Window, and the CSocketWnd window handle is saved in the M_HSocketWindow variable in the current module state.
2. Blocking mode
The communication between the Server end and the Client end in the blocking mode is in a synchronous state.
Instantiate the CSocket class directly in the Server side, call the create method to create a socket, then call the method Listen start listening, and finally use a While loop blocking to call the Accept function to wait for the connection from the Client side, if this Socket is in the main thread (main program) Operation, which will cause the main thread to block. Therefore, you need to create a new thread to run the Socket service.
Debug trace to CSocket :: Accept function Source: while (Accept (...)!) {If (GetLastError () == WSAEWOULDBLOCK) // The socket is marked as nonblocking and no connections are present to be accepted PumpMessage (FD_ACCEPT. Else Return False;}
It continuously calls CasyncSocket :: Accept (CSocket derived from the CasyncSocket class) Decades if there is a connection event in the event queue in the server-side Socket - fd_accept (see 1), in other words, it is to determine whether there is a connection from the Client side Socket request.
If there is an incoming connection event in the event queue of the current Server Socket, Accept returns a non-0 value. Otherwise, accept returns 0, at which point Call GetLastError returns the error code WSAEWOULDBLOCK, indicating that there is no connection request in the queue.
Note that there is a code in the cyclic body:
PumpMessage (fd_accept);
PumpMessage acts as a message pump allows messages in socket Window to remain active. Reactive tracking into the pumpMessage, found that the call of this message pump is not related to the Accept function, it just makes few Socket Window messages (typically the WM_Paint window redraw message) is active, and most of the Socket Window messages Blocked, blocking messages containing wm_socket_notify.
Obviously, if there is no connection request from the Client side Socket, CSocket will continue to call the Accept to generate loop blocking until the blocking request from the Client side socket is removed.
After blocking release, the Server side Socket and Client side Socket have been successfully connected, and the Server ends to call each other with each other to start communication.
3. Non-blocking mode
Using the message mechanism of the Socket event in non-blocking mode, the communication between the Server end and the client end is in an asynchronous state.
It is often necessary to derive a new class from the CSocket class. The purpose of the derived new class is to overreload the message function of the socket event, and then add the appropriate code in the message function of the socket event to complete the communication between the Client end and the Server end. Non-blocking mode does not need to create a new thread compared to blocking mode.
Here will discuss how the Event's processing function onaccept is further triggered after the Server-side Socket event-FD_ACCEPT is triggered. Other events are similar to this, such as onConnect, OnReceive, etc.
When the client / server communication is mentioned in 1, the Server side Socket is receiving from the Client side Socket connection request, which will trigger the FD_ACCEPT event, and the server-side network transport service process sends event notifications to the SOCKET WINDOW (CSocketWnd) of the Server end. WM_SOCKET_NOTIFY message, generating a notification event has FD_ACCEPT, CsocketWnd after receiving the event notification message, call the message processing function OnSocketNotify: LRESULT CSocketWnd :: OnSocketNotify (WPARAM wParam, LPARAM lParam) {CSocket :: AuxQueueAdd (WM_SOCKET_NOTIFY, wParam, lParam); CSocket :: processauxqueue (); Return 0L;}
Message Parameters WPARAM is the handle of the socket, LParam is a socket event. Here is a slight explanation, 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 static member functions of the CSocket class, if you Yuan is not familiar, please quickly find this method of using the C book to see the friend's way! ProcessAuxqueue is a function of substantially handling the Socket event, 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 (see 1)! 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!
The end of this article:
Server Socket is in blocking mode, it must work in a newly created thread to prevent the main thread from being blocked.
When multiple client sockets are connected to the Server side socket connection and communication, the Server terminal uses the blocking mode to be unsuitable. Non-blocking mode should be used, and the message mechanism of the Socket event should be used to accept the connection request of multiple client-side sockets. Communication.
In Non-blocking mode, CsocketWnd utilizes CSocketWnd as all Sockets's message pool, is a key technique for realizing the message mechanism of the socket event.
There is a technical problem in the text, please forgive, please forgive, please criticize, thank you! 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.
2. Socket type
In the TCP / IP protocol, the Client / Server network program uses TCP protocol: The socket type is SOCK_STREAM, which is a reliable connection. Here, the UDP protocol is not used: The socket type is SOCK_DGRAM, which is unreliable connection.
Source code reference:
1 . http://www.codeproject.com/internet/socketFileTransfer.as is a typical example of a Client / Server-end network program based on a blocking mode using a CSocket class.
2 . Http://www.codeguru.com/cpp/in/network/messaging/Article.php/c5453 The CSOCKET class is written based on the CLIENT / Server network program based on non-blocking mode. Typical example.
Attachment: Reference books and articles
• Microsoft MSDN Library - January 2001
• "Windows Network Programming" Tsinghua University Press