Contents
计算机网络中应用层是我们用Cpp或者其他开发语言写的网络程序或者脚本。
当应用层数据传送之后,比如当我们在Qt程序中用QTcpSocket对象write之后,此时,传输层会将用户即将发的内容进行分块打包操作.
TCP头部报文报分析
下面我们看传输层中的一种协议(TCP)的头部内容:
从上图可以看出,TCP报文段首部格式包含20个字节的固定长度和40个字节可变长度。
源端口(2个字节,范围:0-65535):
发送端的端口号
目的端口(2个字节,范围:0-65535):
接收端的端口号
序号(四个字节seq号),
即当前发送的数据首字节在已经发送数据中的个数,假如从TCP开始链接之后,发送了一个aaaaa,当再发送aaaaa的时候,这个第二个aaaaa包的seq为6,证明请看抓包分析的结果
从下面图片可以看出,序列号加上当前数据的长度等于下一个序列号.
确认号(Acknowledgment number):
即给对方说自己现在已经收到多少字节的数据了.但是确认号表示的是对方下一次发送应该发第几个字节的内容了,也即是已经对方发送的数据大小+1.
从下图可以看出,10745端口号这边只发送了10个字节的内容,但是最后一条的ACK却为11,这就验证了刚才的结论.为对方下一个应该发送的数据首字节.
数据偏移:(4个比特位)
它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。“数据偏移”的单位是 32 位字(以 4 字节为计算单位)。
因首部中还有长度不确定的选项字段,故数据偏移字段是必要的
而数据偏移的单位是4字节,则此字段是用来表TCP首部的长度的,最大长度是4*15,60字节,即选项长度不超过40字节.这就是开头说的为什么选项部分最大是40个字节.
看下图,二进制1000表示8,8*4=32,则该包TCP首部为32个字节.
保留:
6个字节,详细请看下面抓包分析.
控制位:
一共6个,占6比特,设置为1时有效。按顺序依次为:URG、ACK、PSH、RST、SYN、FIN。
从这个抓包中分析可以看出,保留6个比特位,控制位占6个比特位.
窗口:
即发送方处理缓冲区,当我缓冲区满了之后,我不希望对方一直发数据.
占2字节,表示报文段发送方期望接收的字节数,可接收的序号范围是从接收方的确认号开始到确认号加上窗口大小之间的数据。
校验和:
校验和包含了伪首部、TCP首部和数据,校验和是TCP强制要求的,由发送方计算,接收方验证。
紧急指针:
URG标志为1时,紧急指针有效,表示数据需要优先处理。紧急指针指出在TCP段中的紧急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长。
选项:(可选内容)
最常用的选项是最大段大小(Maximum Segment Size,MSS),向对方通知本机可以接收的最大TCP段长度。MSS选项只在建立连接的请求中发送。
下面我们根据抓包内容分析TCP三次握手和四次挥手的过程:
TCP三次握手:
(第一次握手)下面是抓包的发起连接会话端发送的内容
前20个字节必选内容
源端口
目标端口
序号(sep):0
确认号(ack number):0
头部长度:40
控制位:SYN置1(为同步(synchronize)的缩写,即发起会话控制位),其他为都为0,ACK现在为0表示该包确认号无效.
窗口大小:65535
校验号:0x8adc
紧急指针:0
后20个字节可选内容
其中包含MSS和其他的选项:
关于MTU和MSS的区别和联系
可参考博客:
https://blog.csdn.net/u011019726/article/details/94740977?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
其大概意思是
MSS+TCP头+IP头,就得到MTU了;
151包里客户端声明mss是1460,意味着MTU就是1460+20(TCP头)+20(IP头)= 1500
153包里服务器声明mss是8960,意味着MTU就是8960+20(TCP头)+20(IP头)= 9000
区分MTU和Window大小
MTU为最大传输单元,即一个数据包最多可以传送多少字节的内容。window size是最多发多少,没有收到回应就停止发送,等回应之后再继续发送。
(第二次握手)下面是抓包的被发起端返回发起端的内容
前20个字节必选内容
源端口
目标端口
序号(sep):0
确认号(ack number):1
头部长度:40
控制位:SYN置1,ACK置为1
窗口大小:65535
校验号:0xoc1a
紧急指针:0
后20个字节可选内容
(第三次握手)下面是发起端给被发起端回复内容
源端口
目标端口
序号(sep):1
确认号(ack number):1
头部长度:32
控制位:ACK置为1
窗口大小:10231*256
校验号:0x8adc
紧急指针:0
TCP四次挥手
总览图:
第一次挥手
源端口
目标端口
序号(sep):1
确认号(ack number):1
头部长度:32
控制位:FIN置为1,ACK置为1
窗口大小:10231*-1(位置)
校验号:见图片
紧急指针:0
第二、三次挥手
因为二三次挥手的发起端和接收端是一致的,因此将他们放在一起。
第二次挥手:
源端口
目标端口
序号(sep):1
确认号(ack number):2
头部长度:32
控制位:ACK置为1
窗口大小:10231*-1(位置)
校验号:见图片
紧急指针:0
第三次挥手
源端口
目标端口
序号(sep):1
确认号(ack number):2
头部长度:32
控制位:FIN置为1,ACK置为1
窗口大小:10231*-1(位置)
校验号:见图片
紧急指针:0
第四次挥手
源端口
目标端口
序号(sep):2
确认号(ack number):2
头部长度:32
控制位:ACK置为1
窗口大小:10231*-1(位置)
校验号:见图片
紧急指针:0