I gave a talk last Sunday in the Free and Open Source Developers’ European Meeting (FOSDEM) 2007 on how Jaiku uses Jabber, aka XMPP, (Slides with notes, even if I don’t usually do that).
I realized that there was this undertone in my talk that TCP is somehow broken by GPRS, since packets get acked even if they are not received by the phone and that the connection breaks a lot and has a large latency. But that’s of course not true: TCP isn’t being _broken_ by this, just our mistaken view of what TCP is.
TCP tends to be describe as reliable: RFC 793 introduces it as a “highly reliable host-to-host protocol”; Wikipedia claims that it “guarantees reliable [...] delivery” and man tcp calls it “reliable” as well.
The trick, is that the “reliability” this documents talk about is quite different with what we tend to think of as reliable. TCP’s reliability means in-order delivery and integrity (no bits flipped). What people often think when they think of reliable is some vague idea of “data getting to the other end”. Which of course isn’t the case.
If you want reliability, you 0) give your data a unique identifier, 1) store persistently the data you are going to send, 2) send it to the other side 3) store the data persistently on the other side, 4) send an acknowledgement to the sender, 5) delete on the sender. TCP does something like this, but it forgets ‘persistently’, since it’s just in the OS buffers which get thrown away if you close the socket, your program, or the machine.
So, guys and gals, TCP is just ordered: if you send x, y and z the received will never receive just x and z. But that’s all. If you want “reliability” you have to do what I described above on the application level.