So we all know that IP addresses allow us to communicate across the network by telling us source and destination layer 3 addresses. But that’s just one bitty part of network communication.
If you’ve been following my blog you know IP addresses is the minutiae of network communication. In fact, IP is nothing without TCP baby! Let’s enter the secret world of TCP and its super exclusive handshake.
Electrical signals are exchanged at the Physical Layer; layer 1. At the data link layer, we have physical addresses, also called MAC addresses, that let us communicate on the local area network. IP networks live at layer 3 and give us end-to-end communication through routers to the final destination.
TCP flirts with IP in the transport layer: Layer 4.
At the Transport Layer we have two big girls: TCP and UDP.
TCP is like that co-worker you can always count on to get the job done. Conversely, UDP is that impetuous friend who quickly volunteers for all the menial tasks but you have no confidence that she’ll do the job right.
UDP is like throwing a brick over a wall, you don’t know where its going to land or even if its going to land. You just send it out and hope it gets there.
TCP builds connections but it’s slower. UDP is great for real time traffic like voice over IP or real time online games while TCP better suited for web applications and email.
So how does it all work? It’s all about the sequences baby.
TCP uses sequence numbers. It numbers all the data segments. When you slap open google.com in your browser, some segments may flow through one set of routers in one country, but as routes go up and down on the internet, you might have a different set of segments travel down a different route in a different country.
Sequence numbers allows the destination to reassemble the segments in the right order so the recipient can make sense of it.
TCP also acknowledges all the segments it sends. It will send back ACKs to your computer so that it knows the destination got the request. If you don’t get the ACK, you’re TCP application will keep sending the request until you get one. TCP is resolute and motivated to get your data to the right place.
With UDP, you would just send a segment with a UDP header and it wouldn’t care if it got there or not.
UDP is like FedEx dropping off a package without ringing the doorbell or waiting for you to open the door.
TCP is different. TCP is like a phone call. TCP is a conversation. TCP gives a damn lol.
Just to clarify: this doesn’t mean UDP sucks it just means it’s better suited for real-time data.
Alright so let’s talk about this secret handshake business…
The secret TCP three-way handshake
When your computer starts the phone conversation, it sends a SYN segment. This is a synchronization segment that says, “Hey, I want to start a conversation with you”.
The destination sends back a “SYN/ACK” which says, “I heard you that you want to talk to me. I’ve acknowledged that. And I’m sending you a SYN so you know I want to talk to you too.”
Then you send an “ACK” acknowledging that you got the response and now you can send data back and forth. That’s the three way handshake.
Whenever you open a website you’re doing this SYN, SYN/ACK, ACK dance behind the scenes. And it all happens in the blink of an eye.
Sequence numbers in depth
Let’s say you send a HTTP request to fixedbyvonnie.com with sequence number 10. Just think of this as a label for a chunk of data.
fixedbyvonnie.com gets the data segment and sends back a reply with its own sequence number of some other number. Let’s use… I don’t know… 5? Yes, okay 5 will work.
Each computer just makes up it own set of sequence numbers so it’s possible your sequence number could have been 1000 and fixedbyvonnie.com could have used 300.
The point here is that the server response not only includes its sequence number but also an ACK flag set to the next expected segment number.
So since our computer sent over SEQ 10 the server will send ACK 11.
This is a crucial concept to understand.
This means that the web sever is saying it received sequence number 10 and it is now waiting for sequence number 11.
Your computer would send sequence number 11 with the ACK field set to ACK 6. This means you got the web server’s segment labeled with sequence number 5 and are now waiting of sequence number 6.
Each one has it’s own set of sequence numbers so the acknowledgements are saying “Yup I got it, and I’m ready for the next one”.
So the web server would say, SEQ 6, ACK 12. which means “I got SEQ number 11 now give me SEQ 12.” Each ACK says “I got it now give me blah” and the SEQ field says: “this is the sequence number of the current segment”
So let’s say one of the segments times out. Maybe the server goes offline. Maybe you go offline. Maybe Godzilla shows up and takes a big bite out of a router in Thailand.
When your computer fails to get the acknowledgment from the server, TCP automatically resends the segment.
So this is good because it guarantees segment delivery, but I have to ask: is it efficient?
If you send one segment and acknowledge it and keep doing this over and over isn’t that a waste of time and resources? It’s like us having a conversation like this:
- You: “So”
- Vonnie: “Got it”
- You: “Vonnie”
- Vonnie: “Got it“
- You: “I”
- Vonnie: “Got it“
- You: “Think”
- Vonnie “Got it“
- You: “You’re”
- Vonnie : “Got it!”
- You: “the”
- Vonnie: “Got it!!”
- You: “most”
- Vonnie: “Got it!!!”
- You: “annoying”
- Vonnie: “GOT IT”
- You: “person”
- Vonnie: “G O T I T!”
- You: “in”
- Vonnie: “got it”
- You: “the”
- Vonnie: “seriously, got it”
- You: “world”
- Vonnie: “yup, got it”
Yeah, talk about inefficient.
Instead of acknowledging every word, wouldn’t it makes sense to acknowledge sentences or maybe whole paragraphs?
Wising up with Windowing
Yes, welcome to TCP Windowing.
TCP can dynamically increase the amount of data it sends based on the fluctuating conditions of the network.
The first time it sends the segment it’ll expect an immediate acknowledgement. So TCP says, “Hmm I sent one segment and received an acknowledgment I wonder what would happen if I sent two segments at once?”
TCP sends two segments and gets an acknowledgement. TCP says, “Very cool! I wonder If I can can step this up a notch. Let me send four segments at once!”
And TCP gets an acknowledgment. TCP will keep doubling the amount of unacknowledged segments until it fails to receive an acknowledgment. In other words, TCP sends the maximum amount of segments possible without getting timeouts.
It’s like throwing an apple at a circus clown and watching him throw it around. And then throwing two apples at him and watching him juggle two apples. And then throwing 4 apples at him and watching him fumble with four. And then hurling 8 apples at him and seeing if he can handle it. If he drops an apple then you’ve given him more than he can handle and you would scale back to 4.
That is what happens with TCP. And this is called TCP windowing. As time passes, TCP will try to send more segments but will take a chill pill when the other side stops giving acknowledgments.
This is how TCP works
So let’s look at an example.
The computer sends over SEQ 1 and the server responds with ACK 2 meaning: “I got segment 1, now send me the segment labeled 2”
The computer says, okay I’ll slide my window size up a bit. This time the computer sends two segments: SEQ 2 and SEQ 3 and the server responds with ACK 4 which means, “C’mon’ computer is that all you got!? Throw more segments at me I can handle this baby!”
So your computer says, “Oh yeah! Check this out” and your computer slides the TCP window up to four segments. SEQ 4, SEQ 5, SEQ 6, SEQ 7. The server responds with….
Not ACK 8 but ACK 7.
Remember the ACK number is the next expected segment so since your computer already sent SEQ 7 but the server is dill expecting SEQ 7 again it will back off by sliding down the window size.
Next, your PC might send SEQ 7 and SEQ 8
And if your computer responds with ACK 10 you know it’s all good in the network neighborhood…
In the real world, the SEQ numbers are just bigger. If you look at packet captures ,you’ll see the SEQ number isn’t 1 or 2 or 3 it’s bigger but that’s just because it’s showing you the amount of bytes it sent. It might start with 1000 bytes of data and then will keep exponentially increasing the window size until it fails to receive an ACK from the server.
You can actually see this cool SYN/SYN-ACK/ACK action happening in Windows when you try copying a large file across the network.
- Have you ever seen the estimated time remaining field say 10 hours remaining?
- And then after a few seconds, drop down to 30 minutes remaining?
- And then after a few seconds, drop down to 2 minutes remaining?
Do you know what’s really going on?
The TCP window is starting with a small number of unacknowledged bytes. So Windows is saying:
If I keep sending 100 bytes at a time then it’s really going take 10 hours to complete this transfer but wait… whoa hold up. I just got an ACK back from that segment so let me send a bigger segment. Let’s try 200 bytes at a time. Oh okay, so that would take 30 minutes to send. That worked too! So lets slide the TCP window up to 400 bytes at a time. Okay so that would take 2 minutes to copy. That worked too.
That’s what’s happening – the time calculation function is the TCP sliding window in action.
The Bottom Line
TCP and UDP are really different. TCP is trustworthy; UDP isn’t.
We also looked at the TCP three-way handshake and explored sequence numbers and acknowledgements. We finished up with TCP windowing which allows efficient communication because you don’t have to wait for acknowledgments after each sent segment.
And that’s how it works. If you love TCP as much as me, give it a shout in the comments below haha.