Socket编程-TCPIP数据包格式详解-包括数据链路层的头部最近在进⾏⼀些路由软件的编程,发现⾃⼰对数据报格式并不是⼗分清楚,所以就查阅了相关资料,总结如下,供⼤家参考,也可以称为⾃⼰⽇后的⼯具。
图中括号中的数字代表的是当前域所占的空间⼤⼩,单位是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⽤⾊控制和慢启动算法
tcpip路由协议校验和:校验范围包括TCP头、数据报内容和概念性伪头部。概念性伪头部⼜包括源IP,⽬的IP,TCP协议号。
紧急指针:指向数据报中紧急数据最后⼀个字节的下⼀个字节。