Blocking Mode
Windows Socket performs I/O operations in both blocking and non-blocking modes. In blocking mode, the operation function to be executed waits until the I/O operation is completed without returning immediately. The thread where the function is located will be blocked here. On the contrary, in non-blocking mode, the socket function will return immediately, regardless of whether I/O is complete, the thread where the function is located will continue to run.
On a socket in blocking mode, calling any Windows Sockets API takes an uncertain wait time. As shown in the figure, when calling the Recv () function, the process of waiting for data and copying data occurs in the kernel.
When calling the Recv () function, the system first checks whether there is prepared data. If the data is not ready, the system is waiting. When the data is ready, copy the data from the system buffer to the user space, and then return the function. In a nested application, when the Recv () function is called, data may not exist in the user space, and the Recv () function will be in the waiting state.
The Windows Socket program uses the "producer-consumer" mode to solve the above problem. In a program, the "producer" reads data and the "consumer" processes the read data as needed. Generally, "producer" and "consumer" exist in two threads. When "producer" Completes Data Reading, the thread synchronization mechanism is used, for example, setting an event to notify "consumer ", after receiving this event, the "consumer" processes the read data.
When you use the socket () function and wsasocket () function to create a socket, the default socket is blocked. This means that when the call to the Windows Sockets API cannot be completed immediately, the thread is waiting until the operation is completed.
Not all Windows Sockets API calls with the socket block parameter will be blocked. For example, when the BIND () and listen () functions are called using the socket in blocking mode as parameters, the function will return immediately. Call Windows Sockets APIs that may block sockets into the following four types:
1. Input operations
Recv (), recvfrom (), wsarecv (), and wsarecvfrom () functions. Call this function to receive data with the block socket as the parameter. If no data is readable in the socket buffer, the calling thread remains asleep until the data arrives.
2. Output operations
Send (), sendto (), wsasend (), and wsasendto () functions. Call this function to send data with the block socket as the parameter. If the socket buffer has no available space, the thread will sleep until there is space.
3. Accept connections
The accept () and wsaacept () functions. Call this function with the socket block parameter and wait for receiving the connection request from the other party. If there is no connection request at this time, the thread will enter sleep state.
4. outbound connection
Connect () and wsaconnect () functions. For TCP connections, the client calls this function to initiate a connection to the server by taking blocking Socket as the parameter. This function does not return a response before receiving a response from the server. This means that the TCP connection always waits for at least one round-trip time to the server.
Using a socket in blocking mode makes it easy to develop network programs. When you want to be able to send and receive data immediately and process a small number of sockets, it is appropriate to use the blocking mode to develop network programs.
Insufficient Socket in blocking mode is manifested in difficulties in communication between a large number of established socket threads. When a network program is developed using the "producer-consumer" model, each socket is allocated a read thread, a processing data line, and a synchronization event, this will undoubtedly increase system overhead. Its biggest drawback is that it will not be able to handle a large number of sockets at the same time, and its scalability is poor.
Non-Blocking Mode
Set the socket to non-blocking mode, that is, to notify the system kernel: when calling the Windows Sockets API, do not let the thread sleep, but let the function return immediately. The function returns an error code. As shown in the figure, a non-blocking mode socket calls the Recv () function multiple times. Kernel data is not ready when the Recv () function is called three times before. Therefore, this function immediately returns the wsaewouldblock error code. When the Recv () function is called for the fourth time, the data is ready and copied to the buffer zone of the application. The Recv () function returns a success instruction and the application starts to process the data.
When you use the socket () function and wsasocket () function to create a socket, it is blocked by default. After creating a socket, call the ioctlsocket () function to set the socket to non-blocking mode. In Linux, the function is fcntl ().
After the socket is set to non-blocking mode, when the Windows Sockets API function is called, The called function will return immediately. In most cases, these function calls call "fail" and return the wsaewouldblock error code. It indicates that the requested operation has no time to complete during the call period. Generally, the application needs to call the function repeatedly until the code is returned successfully.
It must be noted that not all Windows Sockets APIs are called in non-blocking mode and wsaewouldblock errors are returned. For example, this error code is not returned when the BIND () function is called using a socket in non-blocking mode as a parameter. Of course, this error code will not be returned when you call the wsastartup () function, because this function is the first function called by the application, and of course this error code will not be returned.
To set the socket to non-blocking mode, in addition to using the ioctlsocket () function, you can also use the wsaasyncselect () and wsaeventselect () functions. When this function is called, the socket is automatically set to a non-blocking mode.
The wsaewouldblock error is often returned when a function is called using a non-blocking socket. Therefore, at any time, you should carefully check the Returned Code and be prepared for "failure. The application continuously calls this function until it returns a successful response. In the above program list, the while loop continuously calls the Recv () function to read 1024 bytes of data. This is a waste of system resources.
To complete this operation, someone uses the msg_peek flag to call the Recv () function to check whether data in the buffer zone is readable. Similarly, this method is not good. This method causes a high overhead on the system, and the application must call the Recv () function at least twice to actually read data. A good practice is to use the "I/O model" of the socket to determine whether the non-blocking socket is readable and writable.
The non-blocking mode socket is not easy to use compared with the blocking mode socket. To use a non-blocking socket, you need to write more code to handle the wsaewouldblock error received in each Windows Sockets API function call. Therefore, non-blocking sockets are difficult to use.
However, non-blocking sockets control the establishment of multiple connections, uneven data sending and receiving volume, time is not scheduled, obviously has an advantage. This type of socket is difficult to use, but as long as these difficulties are ruled out, it is still very powerful in functionality. Generally, you can consider using the socket "I/O model", which helps applications manage the communication between one or more sockets in an asynchronous manner.
Source:Http://blog.csdn.net/VCSockets/