Back to basics: TCP

Warning: This blogpost has been posted over two years ago. That is a long time in development-world! The story here may not be relevant, complete or secure. Code might not be complete or obsoleted, and even my current vision might have (completely) changed on the subject. So please do read further, but use it with caution.
Posted on 20 Feb 2011
Tagged with: [ b2b ]  [ tcp

TCP is one of the core protocols for the TCP/IP suite. It provides a reliable data connection without you needing to worry about errors, congestion and other communication problems that haunt the internet. But how does TCP work? It’s another edition of the back-to-basics series.

What is TCP?

TCP stands for Transmission Control Protocol. It main purpose is creating a reliable communication channel, however, it means it has a speed-penalty. Most protocols aren’t design for reliability but for speed. Applications who use those protocols must take action to ensure that the data send actually get received by the destination correctly. The reason why those other protocols don’t do these checks themselves is because of speed. The less a protocol has to do, the faster it can send the data out.

TCP is different in that aspect, since it’s created for reliability. It will ensure that the data you have send out, gets received correctly by the other side but it does more: TCP makes use of a “communication link” between two endpoints (most of the time: a client and a server) which needs to be setup and shutdown. It also makes sure that data send in a specific order, will be received in the same order. This might sound strange, but in fact isn’t. There is no guarantee that all your packages on all the routers and switches between you and the other side (see my traceroute blogpost) all travel the same way. Some of them may find a shortcut, or one of those packets get malformed and have to be send again by the client.  The other side will wait for all the packages to come together and glues them back into the data that was originally send.

TCP header

In order to create this reliability, TCP sends it’s data wrapped in a TCP package. This package consists of a header and a data segment. The header is at least 20 bytes in size and could grow up to 60 bytes. It consists of a few important fields:

  • source port
  • destination port
  • flags
  • checksum
  • sequence number

The source port and destination ports are the port-numbers that the TCP connection uses. There can be multiple TCP-connections between clients so in order to differentiate between the packages, the source and destination ports are used (consider them as phone extension numbers). A few standard ports are common: port 25 is used for SMTP traffic, port 21 for FTP, port 22 for SSH traffic etc. Normally, everything below port 1024 is considered reserved.

In order to communicate with a SMTP server with TCP, we must send a package with a certain source port (does not matter, as long as it is a free port on your system) and with the destination port of 25. The SMTP-server has to send data back to the same source-port in order to make sure we receive a package back.

The “flags” are 8 different flags that are mostly needed to connect and disconnect a TCP-connection. The important ones are SYN (synchronize), ACK (acknowledge) and FIN (finish). We will see them later in the TCP handshake chapter.

Next up is the “checksum”. It’s a very simple (16 bit) checksum to decide whether or not the data is transferred ok.

Last item we discus is the sequence number. This number is needed in order to make sure that packages gets ordered in the correct order after we receive them.

TCP Handshaking

Before actual transfer of data can take place, a TCP connect must be established between clients. When a client connects to a server, it sends out a TCP packet wrapped inside a IP packet. The IP packet is more or less like an envelope with a sender and destination IP. As soon as the IP packet is received at the destination, the server will check the TCP packet for a few items. First of all, the TCP packet must have a flag set called ‘SYN’. This tells the server that the client wants to start a new connection. The server will respond with another TCP packet with 2 flags set: SYN + ACK. Basically telling the client it acknowledges the syn(chronization) request. The browser will once again send another TCP packet, with only the “ACK” flag set, telling the server it acknowledge the sync-acknowledgment.

At that point, the connection is opened for both parties and communication can take place.

Closing connections

After communication, the connection should be closed. This again, is not a matter of not sending anymore data, since TCP cannot reliable detect why there isn’t more data coming. So both the server AND the client must terminate the connection. This is done by the server sending a TCP-packet with the FIN-flag set. The client must respond with a FIN-ACK packet. Note that the server does not acknowledge this packet (it’s 2 times 2 packets instead of 3 packets as during the creation of the connection). Important is that the other side MUST do the same thing. So the client must also send a FIN packet, and the server responds with FIN-ACK. Then, and only then, the connection is terminated properly.

Keepalives

If you have played with web-servers, you might know that web-servers do a lot of communication with clients concerning small files. Some of these files can even fit inside one single TCP packet. Now, suppose we as a browser want to download a CSS file from the browser. This is what normally happens:

client: SYN
server: SYN+ACK
client: ACK
client: "GET /style.css HTTP/1.1 ... etc" (all inside 1 TCP packet)
server: <CSS file> (all inside 1 TCP packet)
client: FIN
server: FIN-ACK
server: FIN
client: FIN-ACK.

So for the simple CSS download, we need at least 9 TCP packets from which 7 are just TCP maintenance. By using the “keepalive” option, we tell the web-browser that the TCP connection should stay open, because we want to have more than just this CSS file. We might download java-scripts, images, other css files etc. It saves us starting up and breaking down the connection which, as you can see, can save up LOTS of time when the latency between you and the server is rather large.

Conclusion

TCP is a great protocol when you need reliability, but it can be kind of slow for some purposes. If you don’t need the reliability that TCP offers, opt for another protocol like UDP or RTP instead. Which is what applications like peer2peer or gaming software do. However, since TCP is such a reliable protocol, creating applications for communicating with other clients or servers is really simple.