Send and recv in a simple and simple TCP/IP

Source: Internet
Author: User
The first is to define a concept: Each TCP socket has a send buffer and a receive buffer in the kernel, TCP's Full-duplex mode of operation and the TCP sliding window depend on the two separate buffers and the padding state of the buffer. The receive buffer caches data into the kernel, and the application process does not call read for reading, and the data is cached in the receiving buffer of the corresponding socket. A bit more verbose, regardless of whether the process reads the socket, the data sent to the end is received through the kernel and cached into the socket's kernel receive buffer. The job of read is to copy the data from the kernel buffer into the buffer of the application tier user, and that's it. When the process invokes the data sent by send, the simplest case (and also the general case) is to copy the data into the socket's kernel send buffer and send it back at the top. In other words, when send returns, the data is not necessarily sent to the end (a bit like write writing), and send simply copies the data in the application layer buffer into the socket's kernel to send the buffer. Later I will dedicate an article to the kernel actions associated with read and send. Each UDP socket has a receive buffer, does not send a buffer, conceptually is as long as the data is sent, regardless of whether the other party can receive correctly, so do not buffer, do not need to send buffer.

Receive buffers are used by TCP and UDP to cache data from the network until the application process reads. For TCP, if the application process has not been read and the buffer is full, the action that occurs is to notify the windows in the end TCP protocol to shut down. This is the implementation of the sliding window. It is ensured that TCP is reliable transmission because the TCP sleeve interface receive buffer does not overflow. Because the other side is not allowed to issue more data than the advertised window size. This is the TCP traffic control, and if the other side ignores the window size and emits more data than the window size, the receiver TCP discards it. UDP: When the socket receives a buffer full, the new datagram is not able to enter the receive buffer and the datagram is discarded. UDP is not flow-controlled; a fast sender can easily drown a slow receiver, causing the receiver's UDP to discard datagrams.

The above is TCP reliable, UDP unreliable implementation.

Tcp_cork Tcp_nodelay

The two options are mutually exclusive, and the TCP Nagle algorithm is turned on or off, and the following scenario is used to explain

Typical webserver answer to the client, application layer code implementation process is roughly, generally as follows:

if (condition 1) {

Fill in the contents of the agreement to the buffer_last_modified "Last-modified:sat, May 05:28:58 GMT";

Send (buffer_last_modified);

}

if (condition 2) {

Fill the contents of the agreement to the Buffer_expires "Expires:mon, Aug 2023 05:17:29 GMT";

Send (Buffer_expires);

}

。。。

if (condition N) {

Populate protocol content to buffer_n ... ”;

Send (Buffer_n);

}

For such an implementation, the current HTTP response in the execution of this code, assuming that the M (m<=n) conditions are met, then there will be a continuous m send call, that is not the lower level will be sent to the client to send an M TCP packet? The answer is no, the number of packets in the application layer is beyond control, And the application layer is not to be controlled.

I use the following four hypothetical scenarios to explain this answer

Because TCP is streaming, for TCP, each TCP connection has only SYN start and fin endings, the data sent in the middle is borderless, and multiple consecutive send sends are simply:

If the file descriptor of the socket is set to block, and the send buffer has enough space to hold all the data of the application layer buffer indicated by this send, copy the data from the buffer of the application layer to the sending buffer of the kernel and return.

If the file descriptor of the socket is set to block, but the send buffer does not have enough space to hold all the data for the application layer buffer indicated by this send, then the number of copies can be copied, and then the process hangs until the TCP has free space on the receiving buffer on the end. Notifies the TCP local by Sliding window protocol (another function of the ACK Packet----open window): "Pro, I'm ready, you can continue sending me x bytes of data now," and then the kernel of this end wakes up the process and continues to copy the remaining data to the sending buffer, And the kernel sends TCP data to the TCP side, and if the data in the application layer buffer indicated by send is still unable to copy all the time, then the process repeats ... Until all the data has been copied, return.

Note that for the behavior of send, I have used "copy once", and send and lower layers are sending packets, without any relation.

If the file descriptor of the socket is set to non-blocking and the send buffer has enough space to hold all the data of the application layer buffer indicated by this send, copy the data from the buffer of the application layer to the send buffer of the kernel and return.

If the file descriptor for the socket is set to non-blocking, but the send buffer does not have enough space to hold all the data for the application layer buffer indicated by this send, the number of copies can be copied, and then the bytes of the copy are returned. It involves a little more, and there are two ways to deal with it after you return:

1. Dead loop, always call send, continuous test, until the end (basically not so).

2. non-blocking collocation epoll or SELECT, use these two things to test whether the socket reached the active state can be sent, and then call Send (high-performance server required processing mode).

In summary, as well as refer to the SO_RCVBUF and So_sndbuf mentioned earlier in this article, you will find that in the actual scenario, you can emit how many TCP packets and how much data per packet, in addition to their own server configuration and environmental bandwidth impact, the receiving State can also affect your sending status.

As for why "application layer is also not required to control the sending behavior," This argument is:

Software system layered processing, modules to deal with a variety of software behavior, the purpose is to perform their duties, Division of labor. The application layer only cares about the business implementation and controls the business. Data transfer is handled at a specialized level, so that the scale and complexity of application-level development is greatly reduced, and the cost of development and maintenance is reduced accordingly.

To return to the topic of sending: Before the application layer can not accurately control and complete control of the sending behavior, it is not the control of the? No, it's not. Although not controllable, but also to try to control!

How to control it as much as possible? Now introduce the topics in this section----tcp_cork and Tcp_nodelay.

Cork: Stopper, plug.

Nodelay: Do not delay

Tcp_cork: As far as possible to save data to the sending buffer, save more to send, so that the network's effective load will rise. Explain the problem of this payload simply and rudely. If there is only one byte of data in each package, in order to send this byte of data, and then give this byte outside a thick layer of TCP Baotou, the network running almost all of the Baotou, valid data accounted for only a small part of the large number of access to the server, bandwidth can easily be so depleted. So, in order for the payload to rise, we can use this option to instruct the TCP layer to save as much data as possible when we send it and populate it with a TCP packet and send it out again. This and promotion efficiency is contradictory, space and time is always a bunch of friends!!

Tcp_nodelay: Try not to wait, as long as there is data in the send buffer, and the sending window is open, as far as possible to send data to the network up.

It is clear that the two options are mutually exclusive. How do you choose between these two options in the actual scenario?

Webserver, the download server (FTP send file server), requires a larger bandwidth than the server, with Tcp_cork. The server that involves the interaction, such as FTP to receive the command server, must use Tcp_nodelay. The default is Tcp_cork. Imagine a user who knocks a few byte commands at a time, and the lower level is saving the data, trying to wait until the amount of data is sent again, so the user waits for madness. This bad scene has a special vocabulary to describe the-----sticky (Nian phonetic two) package

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.