TCP报文解析

TCP是一种可靠的、面向连接的字节流服务。源主机在传送数据前需要先和目标主机建立连接。然后,在此连接上,被编号的数据段按序收发。同时,要求对每个数据段进行确认,保证了可靠性。如果在指定的时间内没有收到目标主机对所发数据段的确认,源主机将再次发送该数据段。

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。

 

最大报文段长度MSS(Maximum Segment Size

指明自己期望对方发送TCP报文段时那个数据字段的长度。比如:1460字节。数据字段的长度加上TCP首部的长度才等于整个TCP报文段的长度。MSS不宜设的太大也不宜设的太小。若选择太小,极端情况下,TCP报文段只含有1字节数据,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,网络的利用率就不会超过1/41。若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的TCP报文段。当传输出错时还要进行重传,这些也都会使开销增大。因此MSS应尽可能大,只要在IP层传输时不需要再分片就行。在连接建立过程中,双方都把自己能够支持的MSS写入这一字段。MSS只出现在SYN报文中。即:MSS出现在SYN=1的报文段中

MTU和MSS值的关系:MTU=MSS+IP Header+TCPHeader

通信双方最终的MSS值=较小MTU-IP Header-TCP Header

  

TCP报头结构

 

 

                                     

                                  

图2-5  TCP头部结构

  

源、目标端口号字段:占16比特。TCP协议通过使用"端口"来标识源端和目标端的应用进程。端口号可以使用0到65535之间的任何数字。在收到服务请求时,操作系统动态地为客户端的应用程序分配端口号。在服务器端,每种服务在"众所周知的端口"为用户提供服务。源端口和IP地址的作用是标识报文的返回地址。目的端口指明接收方计算机上的应用程序接口。TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

  

顺序号字段:占32比特。用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段数据部分的第一个字节。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。

  

确认号字段:占32比特。只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效,建立连接时,SYN报文的ACK标志位为0。

每次发送的序列号是系统随机生成的

确认号=序列号+包的大小,图中只加1是不正确的

如果确认号 < 序列号+包的大小,需要重传数据包

 

数据偏移/头部长度字段:占4比特。给出头部占32比特的数目。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的。没有任何选项字段的TCP头部长度为20字节;4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

 

保留:占6比特,为将来定义新的用途保留,现在一般置0。

 

标志位字段:占6比特。共6个,每一个标志位表示一个控制功能,各比特的含义如下:

URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。

ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

SYN:同步序号,用于建立一个连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。

FIN:finish标志,用于释放一个连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

 

窗口大小字段:占16比特。此字段用来进行流量控制。单位为字节数,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个16bit字段,因而窗口大小最大为65535。表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小

  

TCP校验和字段:占16比特。奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

  

紧急指针字段:占16比特。只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

  

可选项字段:占32比特。可能包括"窗口扩大因子"、"时间戳"等选项。最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

 

数据部分字段: TCP 报文段中的数据部分是可选的,不定长度,为上层协议封装好的数据。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

 

 

tcp常用的option选项:

 

TCP三次握手

TCP怎样才能保证可靠的传输任务,就是通过三次握手。通过序列号字段、确认号字段与标志位字段SYN,ACK配合实现

https://images2015.cnblogs.com/blog/964016/201608/964016-20160829221352886-141830767.png

首先由Client发出请求连接即 SYN=1 ACK=0  (请看头字段的介绍), TCP规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是 seq=x

然后 Server 进行回复确认,即 SYN=1 ACK=1 seq=y, ack=x+1,

再然后 Client 再进行一次确认,但不用SYN 了,这时即为 ACK=1, seq=x+1, ack=y+1.

 

TCP四次挥手

通过序列号字段、确认号字段与标志位字段FIN,ACK配合实现

每次发送的序列号是系统随机生成的

确认号=序列号+包的大小,图中只加1是不正确的

如果确认号 < 序列号+包的大小,需要重传数据包

https://images2015.cnblogs.com/blog/964016/201608/964016-20160829222234683-593863018.png

  当客户A 没有东西要发送时就要释放 A 这边的连接,A会发送一个报文(没有数据),其中 FIN 设置为1,  服务器B收到后会给应用程序一个信,这时A那边的连接已经关闭,A不再发送信息(但仍可接收信息)

  A收到B的确认后进入等待状态,等待B请求释放连接, B数据发送完成后就向A请求连接释放也是用FIN=1 表示, 并且用 ack = u+1(如图) A收到后回复一个确认信息,并进入 TIME_WAIT 状态, 等待 2MSL 时间。

为什么要等待呢?

为了这种情况: B向A发送 FIN = 1 的释放连接请求,但这个报文丢失了, A没有接到不会发送确认信息, B 超时会重传,这时A在 WAIT_TIME 还能够接收到这个请求,这时再回复一个确认就行了。(A收到 FIN = 1 的请求后 WAIT_TIME会重新记时)

另外服务器B存在一个保活状态,即如果A突然故障死机了,那B那边的连接资源什么时候能释放呢?  就是保活时间到了后,B会发送探测信息, 以决定是否释放连接。

 注意:中断连接端可以是Client端,也可以是Server端。

 

来个通俗版的解释:

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!(是服务端先关闭,后客户端关闭)

 

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

 

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

 

整个客户端所经历的状态:

 

整个服务端经历的状态:

https://images2015.cnblogs.com/blog/964016/201608/964016-20160829223830324-385717169.gif

栗子1:

TCP链接中主动断开链接netstat观察可能出现的状态流转是:CD

  A.ESTABLISHED->CLOSE_WAIT->TIME_WAIT->CLOSED

  B.ESTABLISHED->TIME_WAIT->CLOSE_WAIT->CLOSED

  C.ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

  D.ESTABLISHED->FIN_WAIT_1->TIME_WAIT->CLOSED

栗子2

一条tcp连接,主动关闭的一方不可能出现的连接状态是:A

  A.CLOSE_WAIT

  B.FIN_WAIT2

  C.TIME_WAIT

  D.FIN_WAIT1

关于Host文件

hosts文件 是一个用于储存计算机网络中各节点信息的计算机文件。

这个文件负责将主机名称映射到相应的IP地址 。

hosts文件通常用于补充或取代网络中 DNS 的功能。

和DNS不同的是,计算机的用户可以直接对hosts文件进行控制。

host文件一个没有扩展名的系统文件,其作用就是用来存储一些常用的网络域名和与其对应的ip地址,当用户输入一个需要登录的网址时,系统就会先去host文件中查找,如果找到了就立即打开该网址,如果找不到就去DNS域名解析服务器中查找。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值