1. Why TCP Has Skicky Packets and How to Resolve¶
When we search online for socket programming, examples usually tell you how to initialize sockets and configure them. In real application developmenet, setting up socket objects/instances may not be enough. Some of you may have found that when using TCP to setup a socket connection between two hosts, say host A and B, sometimes A sends two packets each of size 20 bytes but B receives one big packets of size 40 bytes. This phenomenon is given a nickname called sticky packets. Moreover, UDP protocol doesn’t have Sticky packets. What’s the reason? How to resolve that?
1.1. Reasoning¶
The reason for sticky packets is that TCP is a streaming protocol while UDP is a datagram protocol. Fine, what’s next?
Let’s analogize TCP to a water pipe. There is a pipe connecting A and B. Once A pours some water into the pipe, B’ll receve the water after a while. The pipe has the following features:
The water molecules follow the same order as they were poured into the pipe.
The output volumn equals the input volumn.
The pipe may merge multiple segments of water streams because of the nature of water pipe.
Delay can be long.
The first two features free A and B from worrying the disordering and the loss of water. They are good news. But the third feature is the culprit for sticky packets.
What about UDP? UDP is a datagram protocol, so we can analogize it to a baggage carousel connecting A and B. A repeatively puts luggages onto the carousel, and B gets the luggages as soon as they arrived. The carousel has the following features:
Since each luggage tries its best to reach the destination, depending on the carousel, the order of receiving luggages may be different from the order of sending.
Some luggages may somehow get lost.
Luggages will never be merged.
Delay depends on the carousel speed, but is shorter than water pipe model.
1.2. Solution¶
Sticky Packets is a behavior (should not be treated as a problem because it’s the feature of TCP) developers need to look at. A simple solution is to add a header to each TCP packet at the sender, and the receiver splits received packets based on the header information. There are generally two methods. Pick one that suits your application.
1.2.1. Add a deliminator¶
Add a deliminator at the end of the packet. The receiver searchs for deliminators to split a packet.
1.2.2. Add a packet length¶
Add a packet length at the beginning of the packet. The receiver reads the packet length and then splits the packet based on the length.