In-depth study of blocking and non-blocking modes in csocket programming (zz)

Source: Internet
Author: User

This article is suitable for beginners and intermediate readers

Sometimes, it takes several hours to read, debug, and track excellent source code programs, so that you can grasp some key technical points and essence more quickly. Of course, the premise is to have a general understanding of these technologies.
I have compiled several Program Programs that use the csocket class and use Client/Server (Client/Server) to chat online and transmit files (For details, refer to source code reference). During the debugging of these programs, tracing goes deep into the csocket core source code sockcore. CPP provides a clear view of the running mechanism of the csocket class, and has some experience in writing socket programs in blocking and non-blocking modes.

Note the following before reading this article:

The blocking and non-blocking concepts here are only applicable to server-side socket programs. Socket stands for socket, which is different from socket. Note the upper and lower case of the first letter.
Communication between the client and the server is simple: the server socket is responsible for listening, responding, receiving, and sending messages, while the client socket is only for connection, response, receiving, and sending messages. In addition, if you are not familiar with the principle of using the csocket class to write client/server network programs, please first query (For details, refer to: Books and online help ).
Before that, it is necessary to describe the network transmission service provider, ws2_32.dll, socket event and socket window.

1. Network Transmission Service Provider (network transmission service process), socket event, socket window

The transport service provider exists as a DLL and is loaded by the service process svchost.exe when the Windows operating system is started. When a socket is created, call the API function socket (in ws2_32.dll). The socket function will pass three parameters: Address Family, socket type (note 2) and Protocol, these three parameters determine which type of network transmission service provider starts the network transmission service function. All network communication is completed by the network transmission service provider. Here, the network transmission service provider is called the network transmission service process, as mentioned above, the network transmission service provider is loaded by the svchost.exe service process.
Describes the interface hierarchy between network applications, csocket (wsock32.dll), socket API (ws2_32.dll), and network transmission service processes:

When the client socket communicates with the server socket, both ends will trigger the socket event. Here we only briefly describe two socket events:

  • FD_CONNECT: A connection event, usually triggered when the Client socket calls the socket API function Connect. This event occurs on the Client.
  • FD_ACCEPT: A connection event being introduced. Generally, the Server socket is triggered when it receives a socket connection from the Client. This event occurs on the Server.

The network transmission service process saves the socket event to the event queue of the socket. In addition, the network transmission service process will send the wm_socket_notify message to the socket window to notify the socket event generation. See the detailed description of the socket window below.
After the csocket: create function is called, the socket is created. When a socket is created, casyncsocket: attachhandle (socket hsocket, casyncsocket * psocket, bool bdead) is called ). The function is used:

  • Add the socket instance handle and socket pointer to a ing table variable m_pmapSocketHandle in the current module status (note 1.
  • During the AttachHandle process, a new CSocketWnd instance (derived from CWnd) will be added. Here, this instance is called a socket window, which is further understood as a window message pool for storing all sockets ), check it carefully. Here, the socket is added with an additional s, indicating that multiple sockets will share one message pool.
  • When the Client socket communicates with the Server, the network transmission service process sends the message WM_SOCKET_NOTIFY to the socket window. Note that the CSocketWnd window handle is saved in the m_hSocketWindow variable in the current module status.

2. Blocking Mode

In blocking mode, the communication between the Server and the Client is in the synchronous state. Directly instantiate the CSocket class on the Server side, call the Create method to Create the socket, then call the method Listen to start listening, and finally use a while loop to block the call to the Accept function to wait for the connection from the Client side, if the socket runs in the main thread (main program), this will lead to blocking of the main thread. Therefore, you need to create a new thread to run the socket service.
Debug tracing to CSocket: Accept function source code:

while(!Accept(...)){      // The socket is marked as nonblocking and no connections are present to be accepted. if (GetLastError() == WSAEWOULDBLOCK) 
 PumpMessage(FD_ACCEPT); else return FALSE; }

It constantly calls CAsyncSocket: Accept (CSocket derived from the CAsyncSocket class) to determine whether there is a connection event being introduced in the Server-side socket event queue-FD_ACCEPT (see figure 1). In other words, is to determine whether there is a connection request from the Client socket.
If a connection event is being introduced in the event queue of the current Server socket, Accept returns a non-0 value. Otherwise, Accept returns 0. When GetLastError is called, the error code WSAEWOULDBLOCK is returned, indicating that no connection request exists in the queue. Note that there is a code in the loop body:

PumpMessage(FD_ACCEPT); 

As a message pump, PumpMessage enables messages in the socket window to remain active. The actual tracking enters the PumpMessage and finds that the message pump is irrelevant to the call of the Accept function. It only makes a few socket window messages (typically WM_PAINT window re-painting messages) active, the vast majority of socket window messages are blocked, and the blocked messages contain WM_SOCKET_NOTIFY.
Obviously, if there is no connection request from the Client socket, CSocket will continuously call Accept to generate a Loop Blocking until a connection request from the Client socket is removed.
After blocking is removed, the Server socket and Client socket are successfully connected. The Server and Client call the Send and Receive methods to Start Communication.

3. Non-Blocking Mode

In non-blocking mode, the message mechanism of the socket event is used, and the communication between the Server and Client is asynchronous.
Generally, a new class needs to be derived from the CSocket class. The purpose of the new class is to overload the message function of the socket event, then, add the appropriate code to the message function of the socket event to complete communication between the Client and the Server. Compared with the blocking mode, no new thread needs to be created in the non-blocking mode.
Here we will discuss how the OnAccept function of the Server-side socket event is further triggered after the FD_ACCEPT event is triggered. The trigger methods of other event processing functions such as OnConnect and OnReceive are similar.
When Client/Server Communication is mentioned in section 1, the Server socket is receiving a request from the Client socket connection, which will trigger the FD_ACCEPT event, at the same time, the network transmission service process on the Server sends the event notification message WM_SOCKET_NOTIFY to the socket window (CSocketWnd) on the Server, notifying the occurrence of the FD_ACCEPT event. After receiving the event notification message, CsocketWnd, call the message processing function OnSocketNotify:

LRESULT CSocketWnd::OnSocketNotify(WPARAM wParam, LPARAM lParam) { CSocket::AuxQueueAdd(WM_SOCKET_NOTIFY, wParam, lParam); CSocket::ProcessAuxQueue(); return 0L ; }

The Message Parameter wParam is the socket handle, and lParam is a socket event. The CSocketWnd class is a member of the CSocket class, which means 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 are not familiar with youyuan, please quickly find out how to use youyuan in this C ++ book!
ProcessAuxQueue is a function that essentially processes socket events. This function has the following code:

CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE); 

In fact, the socket pointer pSocket is obtained from the socket handle to send the event notification message: Search from m_pmapSocketHandle (see Figure 1 )!
Finally, WSAGETSELECTEVENT (lParam) extracts the event type, judges the event type in a simple switch statement, and calls the event processing function. Here, the event type is FD_ACCEPT. Of course, you can call pSocket-> OnAccept!

Conclusion
In blocking call mode, the Server socket must work in a newly created thread to prevent the main thread from being blocked.
When multiple Client sockets are connected to and communicate with the Server socket, blocking mode is not suitable for the Server. Non-blocking mode should be adopted, the message mechanism of the socket event is used to receive connection requests from multiple Client Sockets for communication.
In non-blocking mode, using CSocketWnd as the message pool of all sockets is a key technology for implementing the message mechanism of socket events. There are improper words and possible technical problems in this article. Please forgive me and criticize and correct me. Thank you!

Note:

  1. Current module status-a structure used to save the current thread and module status, which can be obtained through AfxGetThreadModule. AFX_MODULE_THREAD_STATE is redefined as _ AFX_SOCK_THREAD_STATE in CSocket.
  2. Socket Type-in the TCP/IP protocol, the Client/Server network program adopts the TCP protocol, that is, the socket type is SOCK_STREAM, which is a reliable connection method. UDP is not used here: the socket type is SOCK_DGRAM, which is an unreliable connection method.

Source code reference:

  1. Http://www.codeproject.com/internet/SocketFileTransfer.aspA Client/Server-based network file transfer program written in the CSocket class. It is a typical example of a Client/Server network program based on the blocking mode.
  2. Http://www.codeguru.com/Cpp/I-N/network/messaging/article.php/c5453A Client/Server-based network chat program written in the CSocket class. It is a typical example of a Client/Server network program based on the non-blocking mode.

References:

  • Microsoft MSDN Library-January 2001
  • Windows Network Programming Tsinghua University Press

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.