TCP’s so-called sticky and unpack problem is one of the weirdest problems in the tech world!

Over and over again, just like stupid Chinese fans rooting for the Chinese football team. Sometimes the same person makes the same mistake over and over again, and sometimes one person makes the same mistake on the front foot and another person makes the same mistake on the back foot. Even the best programmers stumble on this problem, and it takes them a long time to realize they’re wrong. This is especially true for low-level programmers, many of whom die without understanding the error and fixing it, and simply escape.

We can certainly think that the reason is that some people are not good at learning, but so many people, including countless good programmers in TCP sticky and unpack problems in the error, can’t we say, this is actually the reason of TCP itself?

In my opinion, this problem arises because TCP is inherently sinful — the “streaming” protocol of TCP. So, I’m going to blast TCP!

After decades of verification, no application protocol uses the so-called streaming feature of TCP, with the exception of a few network protocols. We must recognize that all application-layer protocols are packet-based, not streaming protocols. Some protocols with the word “Stream” in their names, such as RTP and streaming media, are composed of numerous small packets in sequence, and have nothing to do with the Stream of TCP at all!

Then we can determine that the nature of data is packet, and stream data is a pseudo-name of a certain type of packet data. In fact, TCP flows are based on IP packets.

Because “flow” is a pseudo-abstract concept, streaming protocols are against human nature and the inherent logic of things. The essence of everything is message. Because of this, “flow” led to the sticky package unpacking problem, it is bound to appear again and again, a large number of times.

How are we going to solve the problem after the shelling?

Since TCP has become the de facto foundation, it is unthinkable to eliminate TCP. What we need to do is find the right programming code to solve the sticky unpacking problem. After countless people’s exploration, and the disproof of countless stupid mistakes repeated over and over again, I have discovered that there is only one way to solve TCP sticky and unpack. There is no second way! I assert that any code that differs from my solution is wrong.

The code architecture to completely resolve TCP sticky and unpack problems is as follows:

char tmp[]; Buffer buffer; // Network loop: The network must be read in a loop, because network data is endless. While (1){// Read a stream from a TCP stream of an arbitrary length. Tcp.read (TMP); // Concatenate the stream data with the previous stream data buffer.append(TMP); While (1){MSG = parse(buffer); MSG = parse(buffer); if(! MSG){// The packet is not ready yet, oops, we have met unpack! Break out of the parsing loop and continue reading the network. break; } // Clear buffer.remove(msg.length); // process(MSG); }}Copy the code

This code is the ultimate solution to TCP sticky packet and unpack the code!

This code is correct because it contains two loops: a network loop and a parsing loop.

The network loop is used to read streaming data from the TCP socket. The length of the data read each time is unpredictable, that is, the length of the data read is not guaranteed. This is the problem caused by “streaming”.

The function of parsing loop is to try to parse multiple packets from the spliced stream data. Note that there are multiple messages, not one. Because of the so-called sticky bag problem, there may be multiple, not one. If parsing is not successful, it indicates that there is a unpacking problem, we continue to read network data.

You just need to memorize the correct code above. It’s the same thing if you don’t memorize, eventually you’re going to have to come to the same conclusion and write the same code as I did. So why not cram it now?

Finally, attach the classic error code:

tcp.read(tmp, HEADER_LEN);
header = parse_header(tmp);
tcp.read(tmp, header.body_len);
body = parse(tmp);
Copy the code

Of course such code is wrong, how can such simple code be right? If so, is TCP still TCP?

If you find this article useful, check out the GitHub project: github.com/ideawu/FUCK… Let more people shoot TCP together!

The project also provides code to simulate sticky and unpack, so if you are not convinced, you can write your own client to try.

Related posts:

  1. The ultimate solution to TCP sticky and unpack
  2. The classic TCP socket failed to read packets. Procedure
  3. Send binary data via HTTP POST
  4. Correct posture for IO in Linux
  5. Channel is used for reliable transmission