TCP headers define how segments are structured and managed at the transport layer, encoding critical connection data including port numbers, sequence and acknowledgment numbers, control flags, window size, and error-checking fields. Understanding each field reveals the mechanics behind reliable TCP communication.
A lot of the understanding of how TCP works and how this communication works can be taken from the TCP header. By understanding the TCP header, it'll start forming the full picture of how this TCP segment communicates and how it works.
As we see here, this is the TCP header. And this row right here is representative of the bits, so for each one of these squares right here, this is a bit. So bit 1, 2, 3, 4, 5, 6, 7, 8. For easy reference, I've got it wrapped up into what the byte looks like, so from here to here is one byte. So I've got one, two, three, four bytes across the top that are represented, or 32 bits.
And because I can't put this all sequentially out into this big long line, I actually broke them into, rather than going horizontal, vertical. So this is the 0 through 3 bytes. This is 4 through 7, 8 through 11, 12 through 15, 16 to 19. So total 20 bytes, because we start out with the zero byte and we count up to 19. So we got a total of 20 bytes. Although there are some options that we can add down here.
So let's take a look at each one of these fields that are found within this, and take a look at what components are in each one of these fields, what they do.
Now remember, we have IP addresses which are found in the layer 3 side of this, the packet, and we've got the port that it's associating with, or the service that it's associated with. And so this altogether is what we call a socket. We find this first part in the layer 3 packet, we find the second part in the layer 4 segment.
And then also we've got the destination, but we also have the source. And that source has a layer 3 address that's in there, but then it also has that layer 4 port, and that can be randomly chosen. So I'm going to choose a random port here that we're going to be sending across, and that's going to be used to establish that connection back and forth, so it knows what information it delivered to which browser, which specific tab that you happen to have open on that port. And this is what is the ephemeral port.
So we have two parts to this, and we're going to see that within the header. We're going to see how the ports in this layer 4 show up as a source port and a destination port.
So the first things that we run across within this layer 4 is the source port and destination port. And if we took a look at that, that is 16 bits. And so with the possible combinations that we have when we are dealing with 16 bits, that is why our port numbers are anywhere from 0 to 65,535, or 65,536 different possibilities. So that's where we get that range that we were looking at earlier, that form both our source and our destination port.
Let's talk about sequencing and how the sequencing happens as it's sending from one location to the next. This first segment that's being sent over is going to have some sort of sequence number involved in it. What I was using is, I was labeling these as 1, 2, 3, 4 in the past. But the way the numbers actually look is you're going to see a little different range, and it's probably going to look a little random at first. Maybe this first one is 1,1 and this next one is 2001. Perhaps the next one is even different yet, and we're looking at 255. And so the numbers that you'll see in here may look a little strange for you at first, but we'll talk about the sequencing and how that happens.
Just as a side note for now, essentially what's used is the first byte within the data of that segment — whatever byte number that is, that's what's getting sent across there. So we'll talk about that sequencing and how that sequencing happens, but for now just know that we have to sequence this as we send it over, and that it can be found in the header as well.
Here we actually see it, the sequence number here, and we see that it actually takes up four bytes or 32 bits. So the sequence number is a total of 32 bits, similar to an IP address. It's not an IP address at all, and it looks very different than that, but it is 32 bits long. And we know that 32 bits, or 2 to the 32nd power, is over 4 billion numbers. So 4 billion numbers can exist within here, four billion different combinations. So the sequence number actually can be very large within here.
Now, as it's sending this data over, let's say this is 2022. We already said there's an acknowledgement number that comes back, and that acknowledgement number is going to look very similar to these sequence numbers. In fact, what the acknowledgement number is is going to be the next byte that it's expecting — whatever the next byte that it's accepting. So this acknowledgement number, if this is 2022, maybe the next byte that it's expecting is 322. And so that is the acknowledgement number that it's going to send over.
And for that reason, the acknowledgement number has to be a similar size field to what the sequence number is. And as we take a look at the TCP header, we do see that this field is in fact 32 bits long as well, same as the sequence number.
All right, next up is data offset. Couldn't quite fit it all in there, so we see data off, but it's actually data offset. We see that it's four bits, and so four bits represents up to 16 possibilities, 0 to 15.
What data offset is, is it tells how big the TCP header is, in the number of four bytes. So what we see here is this right here, we have one, two, three, four, five. So what we would see in here for a TCP header at least, we would see at least five that would be in there, but it would be more depending on what options we have available with this. So typically what we would see is a five in there, but if we saw more, that just means that there's additional options that we have in there.
And the reason why it's called data offset is because how shifted is the data from the start of this segment. So it's really from the start of the segment, wherever this is right here, to when you'll actually start seeing the data. So that's the data offset.
The TCP header can send some additional information or some additional options along with it. So this last field deals with different options that we're setting as we're sending TCP segments back and forth. So the way that this is flagged is on whether we have options or not, and how much options we have within there — how much data is within that options field is determined by the data offset.
So the data offset by default is going to be set up to five here, representing five different lines of this that it's going to be sent over. But if we have a few more lines here — let's say we have three more lines built within the option set — then this would actually be eight, and that would be represented in this data offset. So the data offset represents how large that TCP header is, and that TCP header will vary in length depending on how much options there are.
There is something called padding, and that is, let's say we have options within here that are set but it only takes up two and a half lines, then the rest of this would be considered padding. It's just additional bits that are sent across there, because it needs to end on this even numbered line that's right here. It's not going to end in between. And that way the data offset is going to specify, once again, how many lines there are. But we do need a full number of lines for this, and so padding is going to fill in the rest of that.
Then we have the reserve section here. The reserve section is just for future growth. If we want to add things like more options to it or more flags to it, then we can put that here in the reserve section. For now, it's just 000. It's three bits long — 1, 2, 3. So what you'd see in most of your TCP headers at this point in time should be just 000.
This next grouping of bits right here are called flags. As you can see, they're one, two, three, four, five, six, seven, eight, nine of those, and they are just a single bit wide for each one of these. And it's either on or off. And so with these — the NS, the CWR, the ECE — each one of those, it's either going to come in as a zero if it's off or one if it's on. So it's a way to turn on and off different components of what we're trying to either transmit to the other side, or different components of the TCP header. So there's different things that we turn on and off, and that's what a flag is.
So with these flags, the ones I'm most concerned with are the acknowledgement field, the SYN field, and the FIN field. So these are the three fields that I want to take a little more in depth look into.
The rest of these fields do other functionalities. It could deal with some sort of concealment. It could deal with windowing, and if there's some sort of congestion on the line. And if the urgent field is used — so this URG lets you know if the urgent field is set or not. So each one of these has a specific purpose to flag during here. But what I'm most concerned with is, once again, the acknowledgement field, the SYN field, and the FIN field.
So the acknowledgement field that we see in here is just whether this field is going to be used or not, if the acknowledgement is going to be used or not. I've already said that TCP communication uses this field all the time, so most of the time this acknowledgement field is used. When it's not used is the first round of communication, the first time one machine is reaching out to the other machine. There's really nothing to acknowledge, and so since there's nothing to acknowledge, this is going to be set to zero. But after it establishes that connection pretty quickly — it's the second thing that these two devices are sending — it's going to switch that from a zero to a one, because we start using the acknowledgement field. Since we utilize the acknowledgement field, then that switches to a one.
Next we have the SYN field, or the synchronize field. The synchronize is to synchronize sequences, right? Essentially what this is is right at the beginning there's a little handshake that happens between two devices saying, hey, we're going to establish a conversation, we're going to establish a connection, we're going to communicate, so let's synchronize on our communication here.
And so a random number is put into this sequence number as it gets sent over to the other side, and it turns the SYN flag on as it sends it over, and lets the other device know, hey, I'm starting a conversation, this is the number I've chosen to start this communication. And that other device is going to send something back. Similarly, it's going to have a sequence number that it sends over to the other side, and it's going to have that bit turned on, the SYN bit turned on, so that it says, hey, this is the sequence number that I'm going to start out with.
After that, they don't need to synchronize anymore. So really, it's just the first two segments that are sent back and forth, part of this handshake that just says, okay, we're going to communicate back and forth together. So that's the SYN field right there. And depending on what the syncret field is, if it's a zero or one, it actually changes the meaning of several of the other flags within there.
Then we have the FIN bit. The FIN bit is, once again, a one or a zero. It's just one bit long. It's a one or a zero, and it flags the ending. So the last segment that's sent from the sender sends a finish and says, okay, I'm all done. Essentially, we consider this the thank you. It's the thank you segment, to say thank you very much, so I'm finishing this conversation with you.
So we've already mentioned that if there's some sort of congestion along the line, there's a mechanism through acknowledgements that allows not too much data to be sent across. What I mean by that is this PC over on this side and this server over on this side have no idea what connectivity is in between here. It could be poor, it could be really great, it could be both poor and great, meaning that there's certain segments that operate really well and certain segments that don't. But of course, the connection between these two devices are as strong as the weakest link. And so they don't know what they're going to encounter.
And the acknowledgements sent back and forth help mitigate some of those issues, because once again, as the flow is going across here, if one device is not receiving an acknowledgement, then the other device just says, well, I'm not going to send something more until I receive an acknowledgement. So then it will delay in sending the next segments out to the other side. So that's an element to this acknowledgement.
But there's also something called windowing, that allows us to adjust some of the size of the data that's being sent across between these two devices. So we've got this field, window size, and this is a way for one device to notify the other device: I can only accept so much information, and this is the window size I'm willing to accept. So what it will do is it will send, this is the window size that I'm willing to accept, please don't send more data than what I can really take right now.
And so the other side could limit that in both the number of segments it's sending, but it also could limit how much data within that segment that it sends. So as it sends it across, it's not going to overwhelm the other side. So once again, window size is what one device can use to flag the other device that this is what I can accept.
All right, next field we have is the checksum field. The checksum field is going to be an error checking capability on the TCP header itself. And it actually is not just the TCP header, it's also the data. And there's actually some components of the layer 3 packet, the layer 3 header, that's included in that also. So mostly it's the socket information, so it's the destination and source IP address.
But essentially the checksum is going to check a few components. Once again, it's going to check the TCP header, it's going to check the data, and it's also going to check a couple components, the source and destination address of the packet as well.
The next field is the urgent pointer field right here. The urgent pointer field is just to relay some information about which data is urgent, and so we can put that into the urgent data field. And so the urgent data field can be used or not used depending on if this urgent flag is turned off or turned on. If it's turned on, then this flag is then recognized as having information about how urgent some of the data is. So that is the urgent pointer field and the flag that's associated with it.
TechKnowSurge builds IT and cybersecurity professionals through hands-on, concept-first training built around real understanding — not memorization. Free interactive tools, structured programs, and 25+ years of real-world experience, all in one place.
Explore free tools and programs →