www.cnblogs.com/lisuyun/art…


So let’s take a look at what a 16-bit window size actually does.

Windows are divided into sliding Windows and congested Windows.

Sliding window is the size of the window used by the data receiving end, which is used to inform the sender of the cache size of the receiving end, so as to control the size of the data sent by the sender, so as to achieve the purpose of flow control.

Congestion window does not represent cache. Congestion window refers to the maximum number of packets that can be sent by a source data flow in an RTT

TCP uses a Window mechanism to control the flow of data. When a connection is established, each end of the connection allocates a buffer to hold the input data and sends the size of the buffer to the other end. When the data arrives, the receiver sends an acknowledgement containing its remaining buffer size. The size of the remaining buffer space is called a Window, and notifications that indicate the size of a Window are called Window advertisements. Each acknowledgement sent by the recipient includes a window notification. If the receiver application can read the data as fast as it arrives, the receiver will send a positive window notification with each acknowledgement. However, if the sender operates faster than the receiver (due to faster C, P, and U), the received data will eventually fill the receiver’s buffer, causing the receiver to declare a zero window. When a sender receives a zero window notification, it must stop sending until the receiver re-advertises a positive window.

1. The SO_REUSeADDR option is used to reuse local addresses. If the server is enabled and then disabled, sock is in the TIME_WAIT state, and the socket address bound to it is unavailable. After setsockopt is set, even in TIME_WAIT states can be reused immediately. int reuse = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizof(reuse)); SO_RCVBUF and SO_SNDBUF: size of the TCP receive buffer and send buffer of course, even if we set the size of these two items, the system will automatically double them, and not less than a certain minimum value. The minimum value of the TCP receive buffer is 256 bytes and the minimum value of the send buffer is 2048 bytes. The purpose of this is to ensure that a TCP connection has enough free buffers to handle congestion. setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof(sendbuf)); getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, (socklen_t*)&len); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof(recvbuf)); getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, (socklen_t*)&len); SO_RCVBUF and SO_SNDBUF Each socket has a send buffer and a receive buffer, and you can change the default buffer size with these two socket options. Note:

The order of function calls is important when setting the size of the TCP socket receive buffer, because TCP’s window size options are interchanged with SYN when establishing a connection. For customers, the SO_RCVBUF option must be set before CONNECT; For servers, the SO_RCVBUF option must be set before LISTEN.

The size of TCP’s sliding receive window is actually the size of the socket’s receive buffer in bytes.

1, the above is not absolute, the receive sliding window size will vary with the kernel receive buffer can receive data size.

2, as described in the following ‘three’, TCP header only 16 bits indicates a maximum limit 65536, of course, you can use extended 32 bits.

The buffer size of the socket on the server must be set between LISTEN, because the socket generated during accept inherits the buffer size of the listening socket. The buffer size of the socket on the client must be set before conNET, because conNET requires a three-way handshake and notifies the client of its window size. It doesn’t make sense to set buffers after Connet.

Three, because the buffer size in the TCP head is only 16 bits, so its maximum value is 65536, but for some cases need to use a larger sliding window, this time to use extended sliding window, such as optical fiber high-speed communication network, or satellite long connection network, need the window as large as possible. The extended 32-bit sliding window size is used.

Four, sliding window listening and moving rules:

1. Window closing: After receiving the data from the peer end, it confirms the correctness of the data, which will be stored in the buffer for the application program to obtain. But at this time, because the correctness of the data has been confirmed, it needs to send an ACK to the other party, and because the data has not been taken away by the application process, at this time, it needs to close the window, and the left edge of the buffer window slides to the right. Note that the ACK number of the response is the number of the packet sent by the other party. A number sent by the other party may be ACK multiple times due to the opening of the window.

2, window opening: after the window shrinks, once the application process takes out data from the buffer, TCP’s sliding window needs to be expanded, at this time the right edge of the window expands to the right, in fact, the window is a circular buffer, the window’s right edge expansion will use the original application process to take out the content of the buffer. After the window is expanded, you need to notify the peer end of the ACK. In this case, the SEQUENCE number of the ACK is the same as that of the packet received last time.

The Host Requirement RFC strongly recommends not doing this, but TCP must be able to handle this when it occurs on one side or the other.

Five, the send ()/recv ()

Send (): The send function copies data from the application buffer to the kernel buffer, and that’s it.

Recv (): the recv function copies/cuts data from the kernel buffer to the application buffer, depending on the last parameter.

From blog.csdn.net/nodeathphoe…

In this article we use a blocking socket instance on a test machine to illustrate the topic. All the graphs in this article are captured on the test system.

Three concepts to understand

1. Buffer of the TCP socket

Each TCP socket has a send buffer and a receive buffer in the kernel. TCP’s full-duplex mode of operation and TCP traffic (congestion) control depend on these two independent buffers and buffer fill state. The receive buffer caches data to the kernel, which is cached in the socket’s receive buffer until the application process calls recv() to read it. Again, regardless of whether the process calls recv() to read the socket, the data sent from the other end is received by the kernel and cached in the socket’s kernel receive buffer. All recv() does is copy the data from the kernel buffer to the user’s buffer and return it, and that’s it. When a process calls the data sent by send(), in the simplest (and most common) case, it copies the data into the socket’s kernel send buffer, and the send is returned on top. In other words, when send() returns, the data is not necessarily sent to the peer (similar to write files). Send () simply copies the data from the application buffer into the socket’s kernel buffer. Sending is TCP and has nothing to do with sending. The receive buffer is used by TCP to cache data from the network until the application process reads it. For TCP, if the application process has not read, and the receive buffer is full, the action occurs: the receiver notifies the originator, and the receive window closes (win=0). This is the implementation of sliding Windows. Ensure that the TCP socket receive buffer does not overflow, thus ensuring reliable TRANSMISSION of TCP. The other side is not allowed to send data larger than the advertised window size. This is TCP traffic control. If the other party sends data that exceeds the window size regardless of the window size, the receiving TCP will discard it. Check the socket send buffer size of the test machine, as shown in Figure 1

Figure 1

The first value is a limited value, the minimum number of bytes the socket sends in the cache. The second value is the default; The third value is a limit value, the maximum number of bytes the socket sends in the cache. Based on actual testing, the size of the send buffer is set globally by default to 16384 bytes, or 16K. On the test system, the send cache defaults to 16K. Values in the proc filesystem and in SYSCtl are global values, and applications can use setsockopt () to change the size of the send buffer for a socket individually as needed, as described in the article “SO_RCVBUF and SO_SNDBUF of TCP options,” but that’s a separate topic.

2. Receiving window (sliding window)

The size of the initial acceptance window at the end of the TCP connection is 14600, as shown in Figure 2 (129 is the end, 130 is the beginning).

Figure 2

The receive window is a sliding window in TCP. The TCP receiver uses this receive window —-win=14600 to inform the sender that my current receive capacity is 14600 bytes. Later in the process of sending and receiving will continuously with an ACK (ACK all refer to post the acks scene of TCP) informed the size of the state, started his own receiving window as shown in figure 3, and began to send data quantity, according to the size of the receive window, dawn will not send more than receiving capacity amount of data. This plays a role in flow control.

Figure 3

Figure 3 shows that both packets 21,22 are the 21st ACK packet sent by the receiver to the sender, and the receiver acknowledges the first 7240 bytes of data received. 7241 means that the expected packet starts from 7241 and the serial number is increased by 1. At the same time, the receive window has increased from 14,656 (figure 2) to 29120 after a slow start phase. To indicate that the receiver can now receive 29120 bytes of data, and the sender sees this window notification that the sender can send 29120 bytes of data to the receiver when no new ACK is received. In the 22nd packet, the receiver acknowledges the first 8,688 bytes received and notifies itself that the receive window continues to grow to 32,000 bytes.

3. Relationship between a single TCP load and MSS

MSS is usually 1460 bytes in size on Ethernet, and the maximum data load of a single TCP packet is 1448 bytes during subsequent transmission. Please refer to the blog post “1460MSS and 1448 payload of TCP” for the relationship between the two.

Send ()

Example function description: The receiving end 129 as a client to connect to the sending end 130, after the connection does not call recv () to receive, but sleep (1000), to suspend the process, do not let the process to receive data. The kernel caches the data to the receive buffer. After receiving the TCP request, ret = send(sock, BUF, 70K,0) is used immediately. This C statement sends 70K of data to the receiver. So let’s see what happens. Let’s see what’s going on. Figure 4 shows the captured packets

Figure 4.

Figure 4 illustrates that the packet number is equivalent to the sequence 1. The client sleeps before recv () in order to push data into the receive buffer. Server call “RET = send(sock, BUf, 70K,0); This C statement sends 70K of data to the receiver. Because the size of the send buffer is 16K, send () cannot copy all 70K data into the send buffer. Therefore, 16K data is copied into the send buffer first. There is data to be sent in the lower sending buffer, and the kernel starts sending. Upper send () is blocked at the application layer. 2. TCP packet no. 11. The sender sends 1448 bytes of data to the receiver. 3. TCP packet no. 12: The sender still sends 1448 bytes of data to the receiver without receiving the ACK packet containing 1448 bytes. 4. TCP packet No.13: The receiving end sends a 1448-byte confirmation packet to the sending end, indicating that the receiving end successfully receives a total of 1448 bytes. At this time, the receiver does not call recv () to read, and 1448 bytes are currently pushed into the send buffer. Due to the slow start state, the win receiving window continues to increase, indicating that the acceptance capacity is increasing and the throughput continues to rise. 5. TCP packet No.14: The receiving end sends an acknowledgement packet of 2896 bytes to the sending end, indicating that the receiving end successfully receives 2896 bytes. At this time, the receiver does not call recv () to read, and currently 2896 bytes are pressed into the send buffer. Due to the slow start state, the win receiving window continues to increase, indicating that the acceptance capacity is increasing and the throughput continues to rise. 6. TCP packet No.15. The sender sends 1448 bytes of data to the receiver. 7. TCP packet number 16. The receiving end sends a 4344 byte confirmation packet to the sending end, indicating that the receiving end successfully receives 4344 bytes. At this time, the receiver does not call recv () to read, and currently 4344 bytes are pushed into the send buffer. Due to the slow start state, the win receiving window continues to increase, indicating that the acceptance capacity is increasing and the throughput continues to rise. 8. From here on, I’ve omitted a lot of bags and the process is similar to the one above. At the same time, the space of the sending buffer is gradually vacated because the continuously sent data is confirmed by the receiver with ACK. Send () keeps copying the data in the application layer buF to the sending buffer, thus continuously sending and repeating the process. 70K data is not fully sent to the kernel,send() does not care whether it is sent or not,send() does not care whether the sent data is acknowledged or not,send() only cares whether all the data in buF is sent to the send buffer. If not all the data in the BUF is sent to the send buffer, send () blocks the application layer and copies the data in the BUF step by step while waiting for free space in the send buffer. If all the data in the BUF is copied to the send buffer, send () returns immediately. 9. After the slow start stage, the receiving window increases to the stable stage, TCP throughput increases to the stable stage, and the receiving end is in the sleep state all the time. Recv () is not called to copy the data in the kernel receiving buffer to the application layer, and a large amount of data is pressed into the receiving buffer at this time; 10. TCP packets no. 66 and 67, the sender continues to send data to the receiver; 11. TCP packet No. 68: The receiving end sends an ACK packet to acknowledge the received data. ACK=62265 indicates that the receiving end has received 62265 bytes of data, which is currently compressed in the receiving buffer of the receiving end. Win =3456, compared with the win=23296 of the previous TCP packet no. 16, it indicates that the window at the receiving end has been shrunk. The data in the receiving buffer at the receiving end has not been read by the application layer, resulting in the tight space of the receiving buffer. 12. TCP packets no. 69 and 70, the originating end continued to send two 1448-byte data segments to the receiving end within the range of data quantity allowed by the receiving window; 13. TCP packet no. 71, so far, the receiver has successfully received 65160 bytes of data, all are pressed in the receiving buffer, the receiving window continues to shrink, the size of 1600 bytes; 14. TCP packet no. 72: The originating end continues to send 1448 bytes of data to the receiving end within the data amount allowed by the receiving window; 15. TCP packet no. 73, so far, the receiver has successfully received 66609 bytes of data, all are pressed in the receiving buffer, the receiving window continues to shrink, the size of 192 bytes. 16. TCP packet number 74, unrelated to this example, is sent by another application; 17. TCP packet No. 75: The originating end sends 192 bytes of data to the receiving end within the range of data quantity allowed by the receiving window; 18. TCP packet No. 76, so far, the receiving end has successfully received 66609 bytes of data, all are pressed in the receiving buffer, win=0 receiving window is closed, receiving buffer is full, can not receive any data; 19. TCP packets no. 77, 78, 79 are triggered by keepalive, and the ACK response holds the state of the receiving window win=0. In addition, ACK=66801 indicates that 66800 bytes of data are stored in the receiving buffer. 20. From the above process, we should be familiar with the problems explained by the sliding window notification field WIN, as well as ACK confirmation data and so on. It is now possible to conclude that the receiving cache size should be 66800 bytes (this conclusion is not the subject of this article). Send () sends 70K bytes of data, and now 66800 bytes are sent. There are 16K bytes in the send cache, and the amount of data left to copy into the kernel is N= 70K-66800-16K. The receiver is still in the sleep state and cannot recv () data, which will cause the receive buffer to remain overstocked and the window will always advertise 0(win=0). In this state, the sender cannot send any data. The remaining data of send () cannot be copied into the kernel send buffer. As a result, send () is blocked in the application layer. 21. Send () is blocking… The relationship between Figure 4 and Send () is illustrated. So when does send return? There are three return scenarios

Send () Returns a scenario

In scenario 1, we continue the example shown in Figure 4, but here we jump out of the process shown in Figure 4

22. It is time for the receiver to sleep (1000), and the process is awakened, as shown in Figure 5

Figure 5: recv (fd,buf,2048,0); Copy data from the kernel’s receive buffer to the buF at the application layer. After closing the receive window with win=0, the receive buffer is now gradually restored to cache capacity. 0) “such an ACK packet notifies the sender that the receiving window is open;

23. After receiving an ACK packet with the message “win=n(n>0)”, the sender continues to send data within the window’s running data volume. Send buffer data is sent; 24. The receiving end continues to receive data and uses ACK to confirm the data. 25. After receiving the ACK, the sender can clear out some space in the send buffer, and the remaining data of the application layer can be copied into the kernel send buffer continuously. 26. Repeat the above sending process; 27. All 70K data of send () entered the kernel, and send () returned successfully. In scenario 2, we continue the example in Figure 4, but here we jump out of the process shown in Figure 4. 22. If there is a problem with the receiving process or socket, send an RST to the sender. 23. The kernel receives RST and sends -1. Scenario 3, which is not related to the above example, sends (1K) immediately after the connection, so that the sent data can be copied into the send buffer in one go.

Send () Sends a conclusion

In fact, scenario 1 and Scenario 2 show a problem. Send () is only responsible for copying and returns immediately after the copy. It does not wait for the ACK after sending or sending. If the socket has a problem, the RST packet is fed back. If send () has not put all the data into the kernel or sent it, send () returns -1 and errno is set to an error. If send () has already returned when the RST packet is returned, the error caused by the RST will be returned immediately on the next send () or recv () call. Scenario 3 completely shows that send () is returned successfully after the copy is completed. If any error occurs during the sending of data, send () or recv () will be returned immediately.

Where it’s conceptually confusing

1. TCP protocol itself is to ensure reliable transmission, does not mean that applications using TCP to send data is reliable, must be fault-tolerant; Send () and recv () have no fixed correspondence. Send () can trigger recv (). Send () is only responsible for copying data to the kernel, and it will return when it is copied to the kernel. Send () will not wait for ACK; 4. The program error triggered by the send () call may be returned either this time or the next time the network IO function is called.

In fact, if you understand blocking, you can understand non-blocking.

From www.cnblogs.com/lidabo/p/45…

Just because Tcp itself is reliable does not mean that applications sending data over Tcp are necessarily reliable. Whether it is blocked or not, the size of send does not indicate how much data is sent to the peer end. In blocking mode, the send function copies the data requested by the application to the send cache for acknowledgement and then returns it. If the size of the send cache is larger than the size of the request sent, the send function returns immediately and sends data to the network at the same time. Otherwise,send sends the data that cannot be contained in the cache to the network and waits for the peer end to confirm the data. (The receiver confirms the data as long as it receives the data from the cache, but does not need to wait for the recV to be invoked.) In non-blocking mode, the send function simply copies the data to the cache of the protocol stack. If the cache space is insufficient, the send function copies the data as much as possible and returns the size of the successful copy. Such as buffer space available to 0, it returns 1, at the same time sets errno to EAGAIN. Available under Linux sysctl -a | grep net. Ipv4. Send tcp_wmem check system default cache size: net.ipv4.tcp_wmem = 4096 16384 81920 There are three values. The first value is the minimum number of bytes allocated by the socket’s send cache, the second value is the default value (overridden by net.core.wmem_default) to which the cache can grow if the system is not overloaded, and the third value is the maximum number of bytes allocated by the socket’s send cache (overridden by NET). The core wmem_max coverage). Based on actual testing, if the value of net.ipv4.tcp_wmem is manually changed, the changed value will be run, otherwise by default, the protocol stack usually allocates memory by net.core.wmem_default and net.core.wmem_max values. The application should change the send cache size in the program based on the characteristics of the application: socklen_t sendBuflen = 0; socklen_t len = sizeof(sendbuflen); getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len); printf(“default,sendbuf:%d/n”, sendbuflen); sendbuflen = 10240; setsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, len); getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len); printf(“now,sendbuf:%d/n”, sendbuflen); It is important to note that although will send cache Settings became a 10 k, but in fact, the protocol stack will expand twice, is set to 20 k. — — — — — — — — — — — — — — — — — — — case analysis — — — — — — — — — — — — — — — In practical application, if the sender is blocked to send, processing due to network congestion or the receiving end too slow, usually, the sending application looks sent 10 k of data, but only send the 2 k to the cache to end, there are 8 k in the native cache (not send or has not been confirmed at the receiving end). So at this time, the receiving application can receive 2k data. If the receiving application calls recV function to obtain 1K data in processing, at this moment, one of the following situations occurs, both sides are shown as: A. The sending application considers that it has finished sending 10K data and closes the socket: the sending host acts as the active CLOSE of TCP, and the connection will be in FIN_WAIT1 semi-closed state (waiting for the ack from the other party). In addition, the 8K data in the sending cache will not be cleared and will still be sent to the peer end. If the receiving application is still in RECV, it will receive the remaining 8K of data (the receiver will receive the remaining 8K of data before the sender’s FIN_WAIT1 state expires). And get a message that the peer socket was closed (recv returns 0). At this point, you should shut it down. B. The sending application calls send again to send 8K data: If the send cache has 20K space, the available space of the send cache is 20-8= 12K, which is larger than the 8K sent by the request. Therefore, send copies the data and immediately returns 8192. Send () returns 4096. If the value returned is smaller than the size of the request sent, the cache is considered full and must block (or wait for the next socket writable signal through SELECT) The program immediately calls send again, which returns a value of -1, errno= eagain.c. The receiving application closes the socket after processing 1K of data: the receiving host acts as the active close, and the connection is in a FIN_WAIT1 half-closed state (waiting for an ACK from the other party). The sending application then receives a signal that the socket is readable (usually by a select call that returns socket readable), but on reading it finds that the recv function returns 0, so it should call close to close the socket(to send ack). If the sending application does not process this readable signal, but instead is sending, there are two scenarios. If send is called after the sender receives the RST flag,send returns -1, and ECONNRESET is set to ECONNRESET, indicating that the peer network is disconnected IPE signal, whose default response action is to exit the process. If this signal is ignored, send returns -1 and errno is EPIPE(unverified). If it is before the sender receives the RST flag, send works as usual. In the non-blocking send case, if SEND is a blocking call and the socket on the other end is closed (such as sending a large buF at once, exceeding the send cache), send will return the number of bytes successfully sent. If SEND is called again, it will return the same number of bytes successfully sent. D. Network disconnection of the switch or router: After processing 1K received data, the receiving application will continue to read the remaining 1K data from the cache. Then, no data can be read, which requires the application to handle the timeout. The general practice is to set a maximum time for the select to wait. If no data can be read after this time, the socket is considered to be unavailable. The sending application keeps sending the rest of the data to the network, but it never gets acknowledged, so the available space in the cache continues to be zero, which the application needs to deal with. If the timeout is not handled by the application, you can use TCP itself to handle the timeout. For details, see the sySCtl entry: net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_time

 

 

///

www.ixpub.net/thread-1446…

 

In this state, the peer end can continue to receive data. However, if there is still unread data in the receiving buffer of the sender, the RST will be set to abnormally close and the connection will be terminated immediately. There is no TIME_WAIT state. In this case, the peer end cannot receive all data, and an error message is displayed: Connection reset by peer.

 

///

TCP SEND and RECV function parsing

Blog.csdn.net/wjtxt/artic…

First, the concept of sliding Windows

The TCP header of a TCP packet has a window field, which is mainly used to tell the other party how much data it can receive (note that only the data part of the TCP packet occupies this space). This field is negotiated and determined when the communication parties establish a connection, and is constantly updated during the communication process, so it is named sliding window. With this field, the data sender knows if and how much data to send. TCP traffic control is implemented through sliding Windows to ensure that the receiving buffer of both communication parties will not overflow and data will not be lost.

Since the window size is only 16 bits in the TCP header, its maximum value is 65536. However, in some cases, a larger sliding window is needed. At this time, an extended sliding window should be used, such as fiber optic high-speed communication network or satellite long-connection network, which requires the window to be as large as possible. The extended 32-bit sliding window size is used.

Two, sliding window movement rules

1. Window closing: After receiving the data from the peer end, it confirms the correctness of the data, which will be stored in the receiving buffer for the application program to obtain. But at this time, because the correctness of the data has been confirmed, it needs to send an ACK to the other party, and because the data has not been taken away by the application process, at this time, it needs to close the window, and the left edge of the buffer window slides to the right. Note that the ACK number of the response is the number of the packet sent by the other party. A number sent by the other party may be ACK multiple times due to the opening of the window.

2, window open: after window contraction, once the application process from the buffer (sliding window or receive buffer) to retrieve data, TCP’s sliding window need to expand, this time window to the right edge of expansion, to the right window this is actually a ring buffer, the window will use the right edge of the expansion of the original application process to remove the contents of the buffer. After the window is expanded, you need to notify the peer end of the ACK. In this case, the SEQUENCE number of the ACK is the same as that of the packet received last time.

3. Window shrinkage, when the right edge of the window slides to the left, is called window shrinkage. HostRequirement RFC strongly recommends not to do this, but TCP must be able to handle this when it occurs on one end.

Send behavior

By default, send copies a specified length of data to the send buffer. The send function returns only after all data has been copied. Otherwise, the send function blocks or waits for a timeout. If you want to change this default behavior and send data directly to the target machine, you can set the send buffer size to 0, so that when send returns, the data has reached the target machine correctly and completely. Note that this only means that the data has reached the network buffer of the target machine, not that the data has been received by the application layer.

During data transmission, the protocol layer determines the length of data segments in TCP packets based on the sliding window of the peer and the MSS value to ensure that the receiving buffer of the peer does not overflow. If there is no data in the sending buffer of the local party and the sliding window of the other party is 0, the protocol layer starts the detection mechanism, that is, sends one byte of data to the other party at intervals. The interval is adjusted from 30 seconds at the beginning to 1 minute and then stabilizes to 2 minutes at the end. This detection mechanism can not only detect whether the sliding window of the other party changes, but also find whether the other party has abnormal exit.

The push flag indicates that the receiver should submit the data to the application layer as soon as possible. If the amount of data to be sent by the send function is small, for example, less than 1460B (refer to the MSS value), the protocol layer sets the PUSH field of the TCP header to 1. If the amount of data to be sent is large and needs to be split into multiple data segments, the protocol layer sets the PUSH field in the TCP header of the last segmented packet to 1.

4. Recv behavior

By default, recV reads (essentially copies) a specified length of data from the receive buffer. If the receive buffer size is set to 0, RECV reads data directly from the protocol buffer (the sliding window area), avoiding copying data from the protocol buffer to the receive buffer. Recv returns two conditions:

1. The application layer receive buffer passed by the recv function is full

2. When the protocol layer receives a TCP packet with push field 1, the recV returns the actual length of the received data

After the protocol layer receives the TCP packet (saved in the sliding window area), the sliding window of the protocol layer closes (the window value decreases). When the protocol layer copies the data to the receive buffer (sliding window area – > receive buffer), or the application layer calls RECV to receive the data (receiving buffer – > application buffer, sliding window area – > application buffer), the sliding window opens (window value increases). Upon receiving the data update window, the protocol layer sends an ACK to the peer.

The data receiving action of the protocol layer is completely driven by the sending action, which is a passive behavior. Without any interference from the application layer (such as recV operations), the maximum data size that the protocol layer can receive and store is the sum of the size of the window and the size of the receive buffer. In Windows, the default window size is 64K and the default receive buffer is 8K. Therefore, by default, the protocol layer can passively receive and save a maximum of 72K data.

/

Blog.csdn.net/wjtxt/artic…

TCP connection down problem:

From the perspective of TCP, an established TCP connection can be closed in two ways. One is normal closure, that is, four times waving the hand to close the connection. There is also an abnormal shutdown, commonly known as a RESET.

FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT ->LAST_ACK->TIME_WAIT In the four waving processes, ACK packets are automatically completed by the protocol stack, while FIN packets must be actively sent by the application layer through Closesocket or shutdown. After the connection is normally closed, recV returns 0, and SEND receives error code 10058.

In addition, in our daily applications, there are many cases of abnormal connection closure. For example, the application is forcibly shut down, the local network is suddenly interrupted (network card is disabled, network cable is pulled out), and the program is mishandled, which will lead to the connection reset. When the connection is reset, RST packets will be generated, and unreceived (sent) data in the network buffer will be lost. After the connection is reset, send or RECV will get error code 10053(10038 for Closesocket), and the recV will get error code 10054 for send and 10053 for Closesocket.

The operating system provides two functions to close a TCP connection: Closesocket and shutdown. Normally, Closesocket sends a FIN packet to the other party, but there are exceptions. For example, when a worker thread is calling recV to receive data, an external call to Closesocket causes the connection to reset and sends an RST packet to the other party. This RST packet is generated by the worker thread.

Shutdown can be used to close a connection in a specified direction. The function takes two arguments, one for the socket and the other for the closed direction, with values SD_SEND,SD_RECEIVE, and SD_BOTH. If the direction is SD_SEND, the socket sends a FIN packet to the peer regardless of the state (recV blocked or idle). At this point, the local party enters the FIN_WAIT_2 state and the other party enters the CLOSE_WAIT state. The local party can still call recV to receive data. When the direction is set to SD_RECEIVE, the state of the connection is still ESTABLISHED. The local party can still send data. However, if the peer party calls send again, the connection is reset immediately and an RST packet is sent to the peer party. Note the difference with closesocket.