Can TCP and UDP packets be split into pieces?

can TCP packets arrive to receiver by pieces?

Yes. IP supports fragmentation, though TCP generally tries to determine the path MTU and keep its packets smaller than that for performance reasons. Fragmentation increases the datagram loss rate catastrophically. If a path has a 10% packet loss rate, fragmenting a datagram into two packets makes the datagram loss rate almost 20%. (If either packet is lost, the datagram is lost.)

You don't have to worry about this though, and neither does the TCP layer. The IP layer reassembles packets into whole datagrams.

E.g.: if I send 20 bytes using TCP protocol, can I be 100% sure that I will receive exactly 20 bytes at once, not 10 bytes then another 10 bytes or so?

No, but that has nothing to do with packets. TCP is, fundamentally, a byte stream protocol that does not preserve application message boundaries.

And the same question for UDP protocol. I know that UDP is unreliable and packets can not arrive at all or arrive in different order,

The same is true for TCP. Packets are packets. The difference is that TCP has retries and reordering built into the protocol while UDP does not.

but what about 1 packet? If it arrives, can I be sure that it is a complete packet, not a piece?

No, but that's not your problem. The UDP protocol handles datagram reassembly. That's part of its job. (In actuality, the IP protocol does this for the UDP protocol, so UDP does it merely by being layered on top of IP.) If a datagram gets split over two packets, the IP protocol will reassemble it for the UDP protocol, so you will see the complete data.


You can't be sure that they really physically arrive at once. The Data link layers below TCP/UDP might split your packet up if they want to. Especially if you send data over the internet or any networks outside of your control it's hard to predict that.

But no matter if the data arrives in one packet or multiple packets at the receiver. The OS should abstract the concatenation of these packets, so for your application it still looks like everything arrived at once. So, unless you are a kernel hacker, in most cases you don't need to worry if this data is transferred in one or many packets.

For UDP the OS will also do some abstraction, so the application that receives the data doesn't have to know in how many packets the data has been transmitted. But the difference to TCP is that there is no guarantee for the data to actually arrive. It's also possible that the data get's split up into multiple packets, and some of them arrive and some don't. For the receiving application it just looks like a stream of data anyway, no matter if it's complete or not.


Examples. Blocks of contiguous characters correspond to send() calls:

TCP:

Send: AA BBBB CCC DDDDDD E         Recv: A ABB B BCC CDDD DDDE

All data sent is received in order, but not necessarily in the same chunks.

UDP:

Send: AA BBBB CCC DDDDDD E         Recv: CCC AA E

Data is not necessarily in the same order, and not necessarily received at all, but messages are preserved in their entirety.