TCP/IP 数据包格式解析
图中括号中的数字代表的是当前域所占的空间大小,单位是 bit 位。
黄色的是数据链路层的头部,一共 14 字节
绿色的部分是 IP 头部,一般是 20 字节
紫色部分是 TCP 头部,一般是 20 字节
最内部的是数据包内容
黄色部分:链路层
目的 MAC:当前 step 目的主机的 mac 地址
源 MAC:当前 step 的源主机的 mac 地址
类型:指定网络层所用的协议类型,通常是 IP 协议,0x0800
绿色部分:网络层,这里用的是 IP 包头格式
版本:记录数据报属于哪一个版本的协议,如 IPv4 或 IPv6
首部长度:指明 IP 头部长度,单位是字,也就是两个字节。该域的值最小为 5,就是标准的头部长度;最大为 15,表明有扩展部分。
服务类型:用来区分不同服务的需要
数据报总长:包含 IP 头部的数据报的总长度。注意,这里不包括链路层的头部,目前最大值是 65535 字节。
分组 ID:这个域的作用是当一个大的数据报被拆分时,拆分成的小的数据段的这个域都是一样的。
标记:共三个 bit,第一个未使用;第二个 DF(Don’t Fragment),设置成 1 表示这个数据包不能被分割,这个是针对路由器的一条指令;第三个 MF(MoreFragment),如果一个数据包被分割了,那么除了最后一个分段以外的所有分段都必须设置为 1,用来表示后面还有更多的分段没有到达,最后一个设置为 0,用来表示分割的段全部到达。
段偏移量:这个域有 13bit,也就是每一个数据报最多有 8192 个分段。每一个分段的长度必须是 8 字节的倍数,也就是说 8 字节是分段的基本单位,当然分组的最后一个段不做限制。这样最大的数据报长度为 8 *8192=65536 字节,比目前限制的最大数据报长度还多 1,能够满足对网络中所有数据报传送的需求。
生存时间:这是一个生存期计数器,最大为 255s,但是实际上使用的时候用作跳数计数器,当值为 0 时数据报被丢弃,用来避免一个数据报过久的逗留在网络中。
高层协议:这里和链路层的类型作用相同,用来表示更高层的协议,这个数据报里是 TCP
首部校验和:IP 头部的校验和
源 IP 地址:数据报来源主机的 IP 地址
目的 IP 地址:数据报目的主机的 IP 地址
紫色部分:传输层,这里用的是 TCP 协议
源端口号:数据报来源主机的端口号
目的端口号:数据报目的主机的端口号
注意:源 IP 地址,目的 IP 地址,源端口号,目的端口号这四个字段唯一的确定了一个 TCP 链接。
TCP 序号(sq):发送的 TCP 的序号,从 0 开始,实际中这个值就是发送的数据报中内容的字节数,比如我发送的第一个报中 sq=0,数据报内容 20 字节,那么下一个数据报的 sq 就应该是 21。
捎带的确认 (ack): 确认收到上一个数据报,然后 act 的值是指定自己想要收到的下一个数据报的 sq,比如我收到一个数据报的 sq=0,数据报内容 20 字节,那么我的 ack 就应该是 21,用来标明我 sq=0,内容为 20 字节的数据报已经收到,我接下来期望收到的是 sq=21 的数据报。
首部长度:和 IP 头部的长度域类似,这个域用来标明 TCP 头部的长度,单位也是字。
保留:6bit 未使用的域
Flag:从左到右,[URG|ACK|PSH|RST|SYN|FIN]
- ACK 设置为 1 表示前面的确认(ack)是有效的,否则前面的确认应被忽略。
- PSH 表示要求对方在接到数据后立即请求递交给应用程序,而不是缓冲起来直到缓冲区收满为止。
- RST 用于重置一个已经混乱的连接。
- SYN 用于建立连接的过程。在链接请求中,SYN= 1 和 ACK= 0 表示该数据段没有使用捎带的确认域。链接应答则捎带了一个确认,即 SYN= 1 和 ACK=1. 本质上 SYN 位是用来表示 CONNECTION REQUEST 和 CONNECTION ACCEPTED,然后进一步用 ACK 来区分是请求还是应答,的确很高明。
- FIN 用来释放一个连接。它表示发送方已经没有数据要传输了。然后,在关闭一个连接后,关闭进程可能会在一段不确定的时间内继续接收到数据。SYN 和 FIN 数据段都有 TCP 序号,从而保证了这两种数据段被按照正确的顺序来进行处理。
窗口大小:指定了从被确认的字节算起可以发送多少个字节。要深入理解这个域的含义,可以参看 TCP 用色控制和慢启动算法
校验和:校验范围包括 TCP 头、数据报内容和概念性伪头部。概念性伪头部又包括源 IP,目的 IP,TCP 协议号。
紧急指针:指向数据报中紧急数据最后一个字节的下一个字节。