TCP报文解析

1.tcp消息头
20个字节固定头部结构
40个字节头部选项字段

typedef struct _TCP_HEADER
{
short m_sSourPort;       // 源端口号16bit
short m_sDestPort;        // 目的端口号16bit
unsigned int m_uiSequNum;   // 序列号32bit
unsigned int m_uiAcknowledgeNum; // 确认号32bit
short m_sHeaderLenAndFlag;   // 前4位:TCP头长度;中6位:保留;后6位:标志位
short m_sWindowSize;      // 窗口大小16bit
short m_sCheckSum;       // 检验和16bit
short m_surgentPointer;      // 紧急数据偏移量16bit
}attribute((packed))TCP_HEADER, *PTCP_HEADER;

英文为:Initial Sequence Number,简称ISN

1、16位源端口号:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是标识报文的返回地址。
2、16位目的端口号:16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。
3、32位序列号:由接收端计算机使用,重新分段报文成最初形式,意思就是序列号是数据的标号,接收到序列号+1就等于确认号,说明序列号-1的部分以全部接收完毕,序列号就是用于标明数据的标号不是数据本身
4.确认号:只有标志物ACK取值为1的时候确认号字段才有效,为0择无效,tcp规定,在连接建立后所有传送的tcp报文段必须都把ack置为1

主机B发送一个报文段
序号=201 说明该tcp报文段数据载荷的第一个字节的序号为201,假设数据载荷的长度为100字节
ack=1 表示确认号字段有效 
确认号=800 表示已经接收序号到799的数据 现在需要接收序号为800的数据

主机B
序号=800 数据载荷第一个
数据载荷长度=200字节
ack=1 确认号=301 说明主机b收到了主机a的数据确认号到300为止的所有数据

数据偏移字段:用来指出tcp报文段与数据载荷部分的起始处距离tcp报文段起始处有多远
实际上指出了首部长度
首部固定长度为20字节,因此数据偏移字段的最小值为(0101)右下小标2
最大40字节扩展首部,首部最大长度60字节,数据偏移字段最大(1111)

加入首部为20字节 那么数据偏移字段就是0101 0101=5 在数据偏移字段中 一个单位是4个字节 所以就是4x5 =20字节

保留:战6比特,保留今后使用
同步标志位SYN:在tcp连接建立时用来同步序号
{
主机A发送 SYN=1 序号=x 第一次连接不会携带数据 只有首部 序号是进程自己挑选的

主机B 收到报文后 向主机A 发送连接请求 SYN =1 ACK=1 序号=y  确认号=x-1

主机A收到后 会发送一个tcp确认报文段 ACK=1 表示这是一个普通的tcp确认报文段 序号=x+1(第二个报文段) 确认号=y+1 

普通的tcp确认报文段 可以携带数据也可以不携带数据 如果不携带数据 则不消耗序号

}

终止标志位FIN:用于释放tcp连接
{
主机A发送终止报文段 FIN=1 ACK=1 序号=u 确认号=v 用来表示这一个tcp释放报文段 序号=u 他等于之前以发过的数据最后一个序号+1  确认号=之前已经收到的数据+1

主机B收到报文返回tcp确认报文段 ACK=1 序号=v  确认号=u+1 这是对上一个报文的确认
如果此时主机A 还要传输 可以继续传输 主机b需要接收

当没有数据接收时,主机B会发送tcp连接释放 FIN=1 ACK=1 序号=w 确认号=u+1 对之前的数据进行确认

主机A需要在发送一个tcp确认报文段 ack=1 表示这是一个普通的tcp 确认报文段 序号=u+1 确认号=w+1 这里是对tcp连接释放的确认
}

复位标志位RST:用来复位TCP连接
当RST=1时,表明TCP连接出现了异常,必须释放连接,然后在重新建立连接
RST置1还用来拒绝一个非法的报文段或拒绝打开一个tcp连接


推送标志位:接收方的tcp收到标志位为1的报文段会尽快上交应用进程,而不必等到接收缓存都填满后在向上交付

紧急标志位URG:取值为1时紧急指针字段有效;取值为0时紧急指针字段无效

紧急指针:占16比特,以字节为单位,用来指明紧急数据的长度
当发送方有紧急数据时,可将紧急数据插队到发送缓存的最前面,并立刻封装到一个tcp报文中
发送。紧急指针指出本报文数据载荷部分包含了多场的紧急数据,紧急数据之后是普通数据

窗口:占16比特,以字节为单位。指出发送本报文的一方的接收窗口
窗口值作为接收方让发送放设置其发送窗口的依据
这里以接收方的接收能力来控制发送方的发送能力,称为流量控制

校验和:占16比特,检查范围包括tcp报文段的首部和数据载荷两部分
在计算校验和时,要在tcp报文段前面加上12字节的伪首部。

选项:
最大段大小选项
最大段大小是指TCP协议所允许的从对方接收到的最大报文段,最大段大小只记录TCP数据的字节数而不包括其他相关的TCP与IP头部。当建立一条TCP连接时, 通信的每一方都要在SYN报文段的MSS选项中说明自已允许的最大段大小。这16位的选项能够说明最大段大小的数值。最大段大小的默认数值为536字节。任何主机都应该能够处理至少576字节的IPv4数据报。如果接照最小的IPv4与TCP头部计算, TCP协议要求在每次发送时的最大段大小为536字节, 这样就正好能够组成一个576 (20+20+536=576,20字节的TCP头部加20字节的IP头部)字节的IPv4数据报。

最大段大小的数值均为1460,这是IPv4协议中的典型值, 因此IPv4数据报的大小也相应增加40个字节(总共1500字节, 以太网中最大传输单元与互联网路径最大传输单元的典型数值): 20字节的TCP头部加20字节的IP头部。当使用IPv6协议时, 最大段大小通常为1440字节。由于IPv6的头部比IPv4多20个字节, 因此最大段大小的数值相应减少20字节。65535是一个特殊数值, 与IPv6超长数据报一起用来指定一个表示无限大的有效最大段大小值。在这种情况下, 发送方的最大段大小等于路径MTU的数值减去60字节(40字节用于IPv6头部, 20字节用于TCP头部。

选择确认选项
滑动窗口的概念描述了TCP协议是如何管理序列号与确认的。由于采用累积ACK确认, TCP不能正确地确认之前已经接收的数据。由于接收的数据是无序的, 所以接收到数据的序列号也是不连续的。在这种情况下, TCP接收方的数据队列中会出现空洞的情况。因此在提供字节流传输服务时, TCP接收方需要防止应用程序使用超出空洞的数据。

TCP “选择确认”(SACK)能在报文段丢失或被接收方遗漏时更好地进行重传工作。通过接收SYN (或者SYN+ACK)报文段中的“允许选择确认”选项, TCP通信方会了解到自身具有了发布SACK信息的能力。当接收到乱序的数据时, 它就能提供一个SACK选项来描述这些乱序的数据, 从而帮助对方有效地进行重传。SACK信息保存于SACK选项中, 包含了接收方已经成功接收的数据块的序列号范围。每一个范围被称作一个SACK块, 由一对32位的序列号表示。因此, 一个SACK选项包含了n个SACK块, 长度为(8n+2)个字节。增加的2个字节用于保存SACK选项的种类与长度。

由于TCP头部选项的空间是有限的, 因此一个报文段中发送的最大SACK块数目为3。

窗口缩放选项
窗口缩放选项(表示为WSCALE或WSOPT)能够有效地将TCP窗口广告字段的范围从16位增加至30位。TCP头部不需要改变窗口广告字段的大小, 仍然维持16位的数值。同时, 使用另一个选项作为这16位数值的比例因子。该比例因子能够使窗口字段值有效地左移。这样事实上将窗口数值扩大至原先的2^s倍, 其中s为比例因子。一个字节的移动可以用0至14 (包含14)来计数。

假设我们正在使用窗口缩放选项, 发送出去的窗口移动数值为S, 而接收到的窗口移动数值为R,这样, 我们从对方接收到每一个16位的广告窗口都需要左移R位才能获得真实窗口大小。每次向对方发送窗口通告时, 都会将32位的窗口大小向右移动S位, 然后将16位的数值填充到TCP头部。窗口的移动数值是由TCP通信方根据接收缓存的大小自动选取的。

时间戳选项与防回绕序列号
时间戳选项(记作TSOPT或TSopt)要求发送方在每一个报文段中添加2个4字节的时间戳数值。接收方将会在确认中反映这些数值, 允许发送方针对每一个接收到的ACK估算TCP连接的往返时间。

当使用时间戳选项时, 发送方将一个32位的数值填充到时间戳数值字段(称作TSV或TSval)作为时间戳选项的第一个部分; 而接收方则将收到的时间戳数值原封不动地填充至第二部分的时间戳回显重试字段(称作TSER或TSecr)。

借助时间戳选项, 我们能够获待往返时间相对精确的测量结果。但它也为接收者提供了避免接收旧报文段与判断报文段正确性的方法。这被称作防回绕序列号( Protection Against Wrapped Sequence numbers, PAWS)。

用户超时选项
用户超时(UTO)选项是一个相对较新的TCP的功能。用户超时数值(也被称为USER_TIMEOUT)指明了TCP发送者在确认对方未能成功接收数据之前愿意等待该数据ACK确认的时间。用户超时选项允许TCP通信方将自已的USER_TIMEOUT数值告知连接的对方。这样就方便了TCP接收方调整自已的行为(例如, 在终止连接之前容忍一段较长时间的连接中断), NAT设备也能够解释这些信息以帮助设置它们的连接活动计时器。

USER_TIMEOUT = min(U_LIMIT, maX(ADV_UTO, REMOTE_UTO, L_LIMIT) )
其中ADV_UTO是本端告知远端通信方的用户超时选项数值, 而REMOTE_UTO是远端通信方告知的用户超时选项数值, U_LIMIT是本地系统对用户超时选项设定的数值上边界, 而L_LIMIT则是下边。

认证选项
TCP设置了一个选项用于增强连接的安全性,当发送数据时, TCP会根据共享的密钥生成一个通信密钥, 并根据一个特殊的加密算法计算散列值。接收者装配有相同的密钥, 同样也能够生成通信密钥。借助通信密钥, 接收者可以确认到达的报文段是否在传输过程中被篡改过(有非常高的可能性)。


填充:确保报文段首部能被4整除
 

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Modbus TCP是基于TCP/IP协议的Modbus协议的一种实现方式。在Modbus TCP中,报文采用了标准的Modbus协议格式,并通过TCP/IP进行传输。 Modbus TCP报文解析包括以下几个步骤: 1. 解析TCP首部:首先需要解析TCP首部,包括源端口号、目标端口号、序列号、确认号等信息。这些信息可以用来确定报文的发送者和接收者。 2. 解析Modbus应用协议头:Modbus报文的应用层协议头包括从站地址、功能码、数据长度等字段。从站地址用于标识Modbus设备,功能码用于指示所要执行的操作,数据长度表示后续数据的长度。 3. 解析数据部分:根据数据长度字段可以确定数据部分的长度,然后按照功能码的不同进行解析。例如,如果功能码是读取保持寄存器的操作,那么需要解析请求的起始地址和寄存器数量。如果功能码是写单个保持寄存器的操作,那么需要解析要写入的寄存器地址和数值。 4. 校验和验证:Modbus协议中包含了一个校验和字段,用于验证报文的完整性。通常使用CRC校验算法对报文进行校验。 需要注意的是,Modbus TCP报文是以字节流的形式进行传输的,因此在解析过程中需要按照字节的顺序进行解析。此外,由于Modbus协议支持多种功能码和数据类型,对不同类型的报文需要采用不同的解析方式。具体的解析方法可以参考Modbus协议的相关文档或库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值