Casyncsocket multi-thread Environment

Source: Internet
Author: User
Tags case statement
From: http://blog.csdn.net/ydbcsdn/article/details/1804096 Casyncsocket multi-thread Environment
  • Windows Network Programming
Asynchronous selection model is essentially different from normal selection model. This model uses Windows window message mechanism. In Linux network programming, the most common choice is the select model. After the select function is called, the thread becomes congested until timeout or socket-related operations are available, for example, if data can be sent from the peer end of the network, the system kernel will tell the current socket is readable. At this time, the Select function returns and the thread continues to execute. Such select calls are also available in Windows networks, However, to better utilize the Windows message mechanism, Windows is highly scalable based on the traditional beckly socket, known as Winsock.. Winsock provides an asynchronous selection mechanism. It transmits a Network Notification event as a message to a receiving window, and uses Windows message processing mechanism, the network event is transferred to a window for processing. The programmer writes the Window Process (actually a large switch-case statement) to process the network event. The MFC class encapsulates windows APIs and, of course, Winsock APIs. The first encapsulation class of MFC for Winsock APIS is casyncsocket.It not only seals APIs, but also saves programmers the trouble of creating windows, registering window messages, and writing windows. It provides callback interfaces, programmers only need to rewrite the virtual functions they are interested in to Implement Asynchronous calls, which sounds very convenient. but msdn says: You need to manage the congestion and process the network byte sequence by yourself when using the caysncsocket. This is because every asynchronous call to execute the caysncsocket cannot ensure that the program has been correctly executed as required. For example, if you call send to send network data, the possible return value is WsaewouldblockIt indicates that your operation cannot be completed immediately and you cannot return immediately. It tells you not to worry about it, but you do not know if it is actually executed in the future. This requires you to check the return value every time,
Determine the number of sent messages. If not sent, it is first placed in the global buffer (not on the stack) and sent in the onsend callback. casyncsocket uses a hidden window to process network events that interest you (for example Fd_read, fd_write, fd_connect), Since it is a window, there is a thread attribute. All operations in a thread should be linear. That is to say, all Io operations in this thread are serial, and because of the event model, all, all operations will be non-blocking. In fact, the efficiency of such Io threads is very high. Of course, the main point of writing asynchronous Io programs is that, no obvious delay is required for any operation of this thread, because your delay will affect all Io operations of this thread. Why is it designed like this? Because: Only when the asynchronous Io of the same socket is serialized can the operation of this socket be strictly ensured. Imagine that multiple threads call receive (asynchronous) at the same time, and it is very likely that each thread gets a part of the data, but it is not complete.. Csocket is used for synchronous processing of asynchronous operations. For example, send (synchronous) is called to send (asynchronous), while csocket also limits its usage, the maximum limit is the socket created in one thread. I/O methods cannot be called in another thread. The above are all theoretical preaching: In actual use, I will not use csocket. asynchronous sockets or encapsulated asynchronous classes are the best to be mastered in commercial software.. Now many articles only mention asynchronous non-blocking, and mention that receive is "returning immediately...". In actual programming, it is not that simple. From synchronous to asynchronous, in addition to model changes, you also need to pay special attention to memory management,
Because many operations must be completed in the global heap. For example, in a thread: void test () // not in onrecieve, call {unsigned char TMP [1024]; psocket-> receive (TMP, 1024 );} if the psocket object is a synchronization class, OK. the received data is in the TMP array; However, the asynchronous class casyncsocket is different, and the data is not in the TMP array. In actual programming, receive is not directly called, but called in onreceive, and store the data in the heap buffer related to the socket as the buffer for receiving data. Similarly, send should have a sending buffer. When onsend is triggered, call the data in the sending buffer cyclically,
In addition, when wsaewouldblock is returned every time, the system will trigger onsend when there is space in the underlying socket sending buffer of the operating system, and you will be able to execute sending again.
The processing of onreceive events is similar, as long as there is data,
You call receive cyclically until return
Wsaewouldblock is returnedThese are all theories. In fact, we still need to care about the processing of upper-layer interfaces. For example, you need to implement such a basic process:
  • The client sends a command to the server, and the server returns a response to the client to determine whether the logon is successful.
We may write a function login () {send (); receive;}, but now it is in asynchronous mode. login () {While (1) {send (..) // send the data directly when the data volume is exceeded} // send cyclically until wsaewouldblock is returned or the remaining bytes sent are 0; addmsgtosendbuffer (); // (1) copy the unsent bytes to the sending cache. waitforsingleobject (); // (2) Custom Event object getmsgfromrecebuffer () after the onreceive function is triggered; // (3) get a packet prase (); // (4) parsing packet from the receiving buffer;} when sending a large amount of data, because the socket is in asynchronous mode, this cyclic send code segment does not take time, because you do not have to wait for the data to be sent to the other end of TCP through a limited bandwidth, but just copy the data to the network buffer. When the value returned by sending is greater than 0 but less than the total number,
The re-call will trigger wsaewouldblock, And the wsaewouldblock is triggered to enable onsend to be called for future system-triggered events. (1) After a statement is called (with residual data), the system will trigger the onsend event when the network sends a buffer with available space, because as long as the server is connected, the onsend of the socket will be called, in onsend, The send code is called cyclically until wsaewouldblock is returned. (2) The statement is to correctly wait for a response. After onreceive is triggered, the receive data can be returned, then, set an event object with a signal as needed. (3) The statement is completely memory operations. From the above we can see that the process of sending and receiving is not the same. In fact, the sending process is more complex and hard to understand. in addition, in the actual asynchronous I/O Code, a data buffer with a large lifecycle is involved, and the user must ensure reliability at all times. In other words, asynchronous Io programming and memory control are two closely related knowledge points. From the above analysis, we can find that the correct sending of data requires the onsend accurate trigger. You do not need to manually call receive anywhere except onreceive. Receive is passive, which is easy to understand, and onsend is troublesome. In fact, you can only call send in onsend. To send data elsewhere, you only need to add the data to the sending queue and then try to call onsend. Can I directly call onsend? If you have considered the thread synchronization problem, you will not agree with it. Because you may have multiple threads operating the sending queue at the same time. In addition, onsend is of the protected type, so the design of Microsoft should be reasonable. What about window messages? Window messages cannot be obtained. Please refer to the following analysis. Using msgwaitformultipleobjects is a good method: void caysncsocket: onsend (INT nerrorcode)
{
// First of all, the socket processing functions are all in the same window event, that is, the same thread.
// Infinite loop round robin ---- this thread will be permanently occupied by this function, and onreceive will not be called;
// 1 ms scheduled polling ---- theoretically, the worst case will cause the delay of sending (<1 MS)
// Waitforsingleobject waits for the event kernel object, which also causes sending and receive delays;
// Msgwaitformultipleobjects waits for the event Kernel Object and can process other messages when there are other window messages. in this way, it can be quickly sent when the request needs to be sent, ensuring the efficiency and timely triggering of functions such as onreceive.
}

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.