Next, I'm going to talk about the TCP Header. So the TCP Header is the header for TCP, is contained inside of the IP packet which is in turn contained inside of an Ethernet frame. The TCP Header contains a set of fields. There is first of all a set of addresses. Because if you think about it, you want to send data to a certain destination, so you want to give it the IP address of the destination. But once it reaches there, well, where does it go next? Modern operating systems support the ability to run multiple applications at once, you could do multitasking. So then there's a question an operating system is sitting there. Well, which of my applications do you want to talk to? So TCP allows you to address applications. We don't call them addresses, maybe we should, we call them ports. Then term port is a little confusing because if you have a physical router and you're talking about the holes in it that you plug cables into, those are also called ports. So you just have to learn these are two different kinds of ports, the same term is used for both. So we have the source port and the destination port. This defines the application ID that's sending the frame or sending the segment, and the destination application that's going to receive the segment. There is also a sequence number. So TCP supports this concept of streaming, I guess, in this long continuous stream of data. When the other side receives the data, it has to know what index into the data you're talking about, which byte number you're sending. So that's the sequence number, it's just the byte that you're sending. It's used to reassemble the segments in case they arrive out of order. There's also information about the next byte that you're expecting, that's an acknowledgment. So TCP provides for reliability. You can send data and you can be sure it got there because the other side is going to send acknowledgments back, and this is how you send acknowledgments. There's also a window size. So the window size corresponds to the number of bytes the sender is willing to receive. So if you're sending to a little IoT device in a very constrained, can't support much data, has a little tiny buffer inside of it, you can still handle TCP, you can it still run TCP just in small window sizes back to you. So if you have a big beefy server, it's not going to overload your little IoT device. There's also an urgent pointer which is used to indicate whether the segment should be delivered up to the application immediately. So you can send a bunch of segments. In modern kernels, they might store these segments for awhile before they send them up to the application for efficiency reasons. But if the urgent pointer says, it's going to deliver it right away. So this can be used for critical data or control data that you need to process. There is also a set of options. These are used a little bit more than IP options, these are things that are used for encryption, multipathing, determining if there's corruption that's been experienced, and so on. There are also a set of control flags which are using TCP operations to indicate this is an acknowledgment, this is a SYN packet uses server as connection, things like that. There is a checksum field which has an error check covering both the header and the payload. So it'll cover data corruption and both of those parts. There's also a data offset. So this is the location in the packet where the header ends, and the rest of the packet begins. So this is an overview of the TCP header. So putting all this together, I talked about Ethernet, and IP, and TCP, each of these as nested in the other. A thing to keep in mind is that this is only one way to stack encapsulation. You can do encapsulation in all sorts of different ways. You can take an Ethernet packet and encapsulate it inside an IP packet, and then put them inside an Ethernet packet. You can have arbitrary orderings for these different packets. There's different reasons for doing that, and I'll talk about that coming up.