Modbus通讯协议之四——TCP/IP
TCP/IP协议已成为信息行业的事实标准,世界上93%的网络都使用TCP/IP协议(在网络层使用IP协议,在传输层使用TCP协议),只要在应用层使用Modbus 协议,就构成了完整的工业以太网。
综上,要讲清楚Modbus TCP/IP一定要对TCP/IP协议有一个基本的概念,所以我们先从TCP/IP协议讲起。
一、基础知识准备
1、OSI七层模型与Modbus TCP/IP 模型
A、OSI七层模型
OSI模型的目的是为了使两个不同的系统能够容易地通信,而不需要改变底层的硬件或软件的逻辑。它是一个灵活稳定可互操的模型,用来了解和设计网络体系结构。OSI模型的层次图如下所示:
a)物理层
物理层协调在物理媒体中传送比特流所需的各种功能。物理层涉及到接口和传输媒体的机械和电气规约(例:RS232、RS485等)。它还定义了这些物理设备和接口为所发生的传输所必须完成的过程和功能(例:奇偶校验等)。
物理层用通俗地话来说就是负责把逐个比特从一个结点移动到另一个结点。
b)数据链路层
数据链路层把物理层转换为可靠的链路,监督在同一个网路上两个系统之间分组的交付。之前文章中所提到的各种数据帧从属于数据链路层。
数据链路层用通俗地话来说就是负责把帧从一个结点移动到另一个结点。
c)网络层
网络层负责把分组从源点交付到终点,这可能要跨越多个网络(链路),这时就需要在众多的可能路径中选择一个最优路径,网络层能确保每一个分组能够从它的源点到达终点。
网络层用通俗地话来说就是负责把逐个分组从源主机交付到目的主机。
d)传输层
传输层负责把完整的报文进行源点到终点(端到端)的交付。
e)会话层
会话层是网络的对话控制器,它建立、维持通信系统之间的交换,并使这些通信系统同步。
会话层用通俗地话来说就是负责对话的控制和同步。
f)表示层
表示层考虑的是两个系统所交换的信息的语法和语义。
表示层用通俗地话来说就是负责转换、压缩和加密。
g)应用层
应用层使用户接入到网络。应用层给用户提供了接口,也提供了对许多种服务的支持。例如:Modbus(自动化信息传输),FTP(文件传输协议),http(超文本传输协议)。
B、Modbus TCP/IP 模型
Modbus TCP/IP简化了OSI模型,它省略了表示层和会话层,其模型如下所示:
物理层,提供设备的物理接口;数据链路层,在同一网络中传输数据帧;网络层,实现带有32位IP地址的IP报文包;传输层,实现可靠性连接、传输、查错、重发、端口服务、传输调度;应用层,Modbus协议报文,这个后续介绍。
以上就可实现工业以太网数据交换。
二、Modbus TCP/IP模型的分层介绍
1、物理层
Modbus TCP/IP的物理层采用以太网物理层,它规定了物理介质、物理接口、物理编码方式。
A、物理介质
物理介质一般采用网线、同轴电缆、光纤。
a)网线
我们工作生活中常见的网线有五类线(用于10M网或100M网)、超五类线(用于1000M网)、六类线(用于1000M网,性能远优于超五类线),网线的最大传输距离均为100m。
b) 同轴电缆
同轴电缆分为粗缆(RG-11)和细缆(RG-58),粗缆特征阻抗为75Ω,最大传输距离为500m。
粗缆弹性差不合适室内狭窄环境安装,安装时不需要切断电缆,可靠性高,但需要配置转换器及相应电缆,线缆成本及安装附件成本高,一般用于主干网络。
细缆特征阻抗为50Ω,最大传输距离为185m。细缆安装时需切断电缆,安装BNC接头,连接至T型连接器,所以易有接触不良的隐患,但其线缆成本及安装附件成本低,一般用于终端网络。
c) 光纤
光纤分多模光纤和单模光纤,单模光纤的传输距离长于多模光纤。传输距离除与光纤的每公里衰减值还和最大发信功率、接收灵敏度、功率裕度有关,这里只给出常用规格的光纤最大传输距离最小值:多模光纤为550m,单模光纤为5km。
B、物理接口
最常见的就是RJ45接口,它有两种线序——T568A与T568B,其示意图如下图所示:
从上图可以看到,两种线序的差别仅仅是1与3互换,2与6互换,其余线序不变。
在讲实际应用前,我们先来引入两个概念:
a)MDI
MDI表示级联口,用于终端与网络中继设备之间连接,普通主机与路由器(WAN)的入网接口通常为MDI,还有集线器和交换机上用于连接另一个集线器或交换机的uplink端口一般也为MDI;
b)MDIX
MDIX表示普通口,用于同种设备(终端设备与终端设备)的连接,集线器、交换机与路由器的LAN口等集中接入设备的接入端口通常为MDIX。
下面我们来介绍不同工况中双绞线的线序选择:
普通主机与集线器之间的连接用直通线,即双绞线两端均采用相同线序,工程中一般两端均以T568B线序制作。
交换机与交换机之间的连接,通过uplink端口连接时采用直通线连接,如没有uplink端口,那么就需要采用交叉线连接,即双绞线一端用T568A线序,另一端用T568B线序。
综上,异种接口采用直通线,而同种接口采用交叉线。
还有一种特殊接法,当制作console线(一端为RJ45接头,另一端为串口接头,用于对交换机进行配置与管理)时,采用反转线,即双绞线一端用T568A线序,另一端将T568A线序倒着接。
现在较为新式的交换机,往往带有Auto MDI/MDIX,可自动识别连接网线类别,无论是交叉线还是直通线均可成功通信。
C、物理编码方式
物理编码方式中决定了线路编码解码、串并行转换、CRC校验、时钟与数据的绑定发送及、将时钟从数据中恢复等等功能。
作为运维人员只需掌握物理介质及物理接口即可,物理编码本人不太了解,不敢乱说。
2、数据链路层
A、MAC地址
MAC地址俗称网卡地址,也叫物理地址,硬件地址或链路地址。由网络设备制造商生产时,在串行EEPROM中写入一个唯一的MAC地址,可以说MAC地址就是网络设备的身份证。MAC地址一般不可改变,不可由用户自行设定。
MAC地址的长度为48位(6个字节),通常表示为12个16进制数,每2个16进制数之间用冒号隔开,如08:00:20:0F:8A:6C就是一个MAC地址,其中前6位16进制数08:00:20代表网络硬件制造商的编号,它由IEEE(电气与电子工程师协会)分配,而后3位16进制数0F:8A:6C代表该制造商所制造的某个网络产品的系列号。每个网络制造商必须确保它所制造的每个以太网设备都具有相同的前三个字节以及不同的后三个字节。这样就保证了MAC地址的唯一性。
数据链路层是基于MAC地址进行帧的传输。以太网通过MAC地址来唯一标识网络设备,并实现局域网上网络设备之间的通信。
B、以太网帧
以太网帧的结构图如下所示:
目的地址和源地址:这里所说的地址就是上文中所提到的MAC地址,目的MAC与源MAC各占6个字节。
类型:用于标识上层协议类型,如IP(0x0800)、ARP(0x0806)、RARP(0x8035)、
数据:它包含了网络层头部、传输层头部、上层应用协议的数据等,数据部分的长度范围为46到1500字节。不足46字节的数据将被自动补足到46字节。如ARP协议的数据格式为28字节,为了符合规范,其后被填充18个字节以达到最少46字节的要求。
PCS:即帧校验字段,用于保存对帧内数据进行校验后得出的校验值,保证数据传输的正确性,一般采用CRC校验,在物理层实现。
以上就是以太网帧中的主要结构及功能了,下面概括一下流程:
发送时,接收端的MAC地址作为目的地址,以太网帧在封装完成后通过物理层转换为比特流在物理介质上传输。
接收时,当接收端接收到的数据帧所包含的目的MAC地址是自己时,会把以太网帧封装剥掉后送往上层协议。如果目的MAC地址不是本机MAC地址,则主机则会丢弃收到的帧。
3、网络层
A、IP地址
IP地址,又叫逻辑地址,是一个32位的二进制数,通常被分割为4个“8位二进制数”,也就是 4个字节。IP地址通常用点分十进制表示成(a:b:c:d)的形式,其中,a、b、c、d都是0~255之间的十进制整数,例如192.168.0.1就是一个IP地址,它在本地是唯一的,在全局上不一定。一般由Internet服务商向有关组织申请一组IP地址,而后通过DHCP动态分配其给用户。
IP地址由网络地址和主机地址两部分组成,分配给这两部分的位数随IP地址编址方案不同而不同。网络地址用于路由选择,而主机地址用于在网络或子网内部寻找一个单独的主机。IP地址类别示意图如下所示:
A类地址(大型网络)数量较少,只有126个但每个网络可容纳1600多万台主机。其IP段为1.0.0.0-126.255.255.255,子网掩码为255.0.0.0。
B类地址(中型网络)有16384个网络,每个网络可容纳6万多台主机。其IP段为128.0.0.0-191.255.255.255,子网掩码为255.255.0.0。
C类地址(小型网络)有209万余个网络,每个网络仅能容纳254台计算机。其IP段为192.0.0.0-223.255.255.255,子网掩码为255.255.255.0。
这三类地址中又分为公有地址和私有地址。公有地址分配给注册并向Inter NIC提出申请的组织机构,通过它直接访问因特网。而私有地址属于非注册地址,专门为组织机构内部使用,即用于局域网。在工业控制领域往往使用就是C类的私有地址。
A类的私有地址为10.0.0.0-10.255.255.255,B类的私有地址为172.16.0.0-172.31.255.255,C类的私有地址为192.168.0.0-192.168.255.255。
注意:
1、上述地址中的第一个(如1.0.0.0)表示网络号,即整个网络本身,用于寻址,最后一个(如126.255.255.255)表示广播地址,这两个地址是不能配置在计算机上的。
2、IP地址中不能以十进制“127”作为开头,该类地址中数字127.0.0.1到127.255.255.255用于回路测试。例如127.0.0.1被称为本地回环地址,如能ping通127.0.0.1则说明本机网卡及IP协议安装均无问题。
3、B类地址中的168.254.0.0-168.254.255.255为保留地址。当主机设置为自动获取IP地址时,而主机在网络上又没有寻找到可用的DHCP服务器,这时主机会随机得到其中一个IP。
4、0.0.0.0表示当前主机地址,255.255.255.255表示为当前子网的广播地址。
补充:
1、其实关于A、B、C类的划分已经没有什么意义了,由于现在对IP进行了子网划分,B类IP地址实际可能是用作C类IP地址。不过A、B、C类的地址分类还是存在的。由于历史原因,所有的A类地址都在美国,例如通用电气的17.0.0.0/8,苹果的3.0.0.0/8等。
D类地址(组播用),不区分网络号及主机号,其IP段为224.0.0.0-239.255.255.255。多点广播用来一次寻址一组计算机,它标识了共享同一协议的一组计算机。它不能作为源IP地址字段。
这里初步介绍一下组播,组播广泛应用于远程多媒体会议,远程教学,视频点播等领域。组播的数据流向图如下所示:
在图中主机A和主机C在组播组中,主机B不在,所以无数据流向主机B。
用组播IP地址(D类地址)进行标识的一个集合,是一个组播成员的集合,各组播成员共享这个组播IP地址(可理解为所有接收者的单播地址与组播组地址形成了映射关系)。
有一点需要注意,我这边单独提出来一下,不要认为IP组播中所有组播设备上的IP地址都是使用组播地址,实际上只有组播组IP地址是组播IP地址(D类),而像组播源,接收者主机的IP地址依旧是单播地址(A、B、C类)
这里提出一个概念:要在Internet完成通信,必须要把将三层的IP地址映射至二层的MAC地址。
组播同样遵循这个原则,组播的MAC地址高25位的前缀固定为0000 0001 0000 0000 0101 1110 0。MAC地址的低23位为组播地址(D类地址)的低23位。其映射关系如下图所示:
举个例子,比如组播IP 224.1.1.1,根据上述关系,可得其对应的MAC地址为01:00:5e:01:01:01,,显然还有2的5次方(32)个IP组播地址对应此组播MAC地址,所以主机CPU必须对收到的每一个组播数据包作出判断,这增加了主机CPU的开销。
对组播的简介到此为止,了解一下就好,在工控领域,没有什么应用。
E类地址(保留作研究用),不区分网络号及主机号,其IP段为240.0.0.0-255.255.255.255。
B、IP协议
a)协议包头
IP协议的包头其结构型式如下图所示:
版本(4位):用来标识IP协议的版本,最常见的就是4和6,分别代表IPV4和IPV6。
首部长度(4位):用来描述IP包头的长度,该部分的单位为32bit(4个字节)。即本区域的值=IP头部长度(单位为bit)/32。举个例子:如果一个IP包头中这个区域的值为0110,那么IP包头长度就是6*4=24字节。IP包头的最小长度为20字节,最大为60字节。
服务类型(8位):服务类型字段包括一个3bit的优先权字段(现在已被忽略),4bit的TOS子字段和1bit未用位(必须置0)。4bit的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。4bit中只能置其中1位。如果4位均为零,那么就表示一般服务。
总长度(16位):用来描述整个IP数据报的长度,以字节为单位。参照首部长度,即可得出IP数据报中数据内容的起始位置和长度。该字段为16位,所以IP数据报最长可达65535字节。当数据被分片时,该字段的值也随着变化。
标识(16位):主机或路由设备将一个数据报拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。
标志(3位):最高位无效;中间位表示DF,只有在DF=0时,才允许对其进行分片,当DF=1,表示此数据报不能分片;最低位表示MF,当MF=1时,表示此IP数据报后面还有分片的数据报,而MF等于0时,则表示当前的IP数据报是这一组中最后一个数据报。
片偏移(13位):此域表示当IP数据报因超过MTU而被分拆成多片后,每一片在原IP数据报中的位置。此偏移量的参照起点是原数据报的数据部分的起点。接收端靠此来组装还原IP包。
生存时间(8位):简称TTL,它决定了数据报可以经过的最多路由器数。TTL的初始值又源主机设置(通常为32或64),一旦经过一个处理它的路由器,它的值就减1。当该字段的值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。此字段可防止由于路由环路而导致IP包在网络中不停被转发。
协议(8位):标识了上层所使用的协议。如TCP为6,UDP为17。
首部校验和(16位):用来校验IP包头的正确性检测,不包含数据部分。因为每个路由器要改变TTL的值,所以路由器会为每个通过的数据包重新计算这个值。计算方法为:
发送端:初始计算校验和字段时,该字段全部用0填充,然后以IP包头的16位为一个单位,逐个做模2加法,在之前的CRC校验中讲过,相当于异或运算,最后将模2加法后得到的结果取反,作为校验和放入校验和字段。
接收端:将接收的IP包头以16位为单位逐个求和,若结果为16位全为1,则校验正确,否则出错丢弃。
源IP地址(32位)与目的IP地址(32位):标识了IP数据报的源地址与目的地址,一般来说,在整个传输过程,这两个地址不会改变。
以上为IP包头的基本字段,共计20字节。后面的可选项,主要用于测试。由于可选项为可变长字段,加之首部长度的单位为32bit,因此在可选项后面,IP协议会填充若干个0,以达到32bit的整数倍。
b)IP分片
谈到IP分片,我们不得不引入一个概念——MTU。MTU是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。
MTU越大,则一个协议数据单元的承载的有效数据就越长,传送相同的用户数据所需的数据包个数也越少,通信效率也就越高。但相对的,MTU越大,传输延迟也越大并且数据包中发生错误的概率也越大,所以MTU的取值并不是越大越好。
以太网的MTU值是1500字节。当一个IP数据报的长度大于1500字节时,就要进行分片传输。分片传输的IP数据报不一定按序到达,但IP包头中的信息能让这些数据报片按序组装。IP数据报的分片与重组是在网络层完成的。
下面举个例子说明分片过程,假设发送端的高层向IP层发送了长度为3200bytes的数据报文,则该报文在添加20bytes的IP包头后,IP包的总长度是3220bytes。显然,这份IP数据报要进行分片。分片时仅对上层的数据进行分片,不需要对原来的IP首部分片,所以要分片的数据长度为3200。
分片过程如下:
1、计算最大IP包中IP净荷长度=MTU-IP包头长度=1500-20=1480。
2、将要分片的数据段(3200bytes)按照1480byte的长度进行分片,3200=1480+1480+240,共计3片。
3、最后发送者将3个分片分别添加IP包头,组成3个IP包后再发送,3个IP包的长度分别为1500bytes、1500bytes、260bytes。
IP数据报分片后,只有到达目的地后才进行重组;如果其中一片数据丢失,那么整个数据报将被重传。超时重传由上层协议负责。
C、ARP协议
a)报文结构
在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址,而数据包必须要通过数据链路层才能送往上层协议,如果接收到的数据包的硬件地址与本机不符,则直接丢弃,因此在通讯前必须获取目的主机的硬件地址。
而ARP协议就是帮我们牵线搭桥的好伙伴。首先我们来认识一下ARP报文的基本结构,其示意图如下所示:
硬件类型(2字节):定义网络类型,以太网的取值是0x0001。
协议类型(2字节):定义网络层协议类型,IPV4的取值是0x0800。
硬件地址长度(1个字节):定义硬件地址的长度(单位:字节),MAC地址长度为6个字节,所以取值为0x06。
协议地址长度(1个字节):定义协议地址的长度(单位:字节),IP地址长度为4个字节,所以取值为0x04。
操作类型(2个字节):定义操作类型,如上图所示,0x0001为ARP请求,0x0002为ARP应答。
发送者以太网地址与发送者IP地址:即源主机的MAC地址与IP地址。
目标以太网地址与目标IP地址:即源主机所请求的MAC地址与IP地址。
注意:
1、以太网帧的数据部分最小长度为46字节,而ARP协议只要28字节,所以在实际报文中会填充18字节的0。
2、ARP请求包是广播,而ARP应答包是单播。
3、ARP请求包中的目的MAC地址填充为FF:FF:FF:FF:FF:FF。
b)ARP高速缓存
ARP缓存是一个缓冲区,用来存储IP地址与MAC地址的对应关系,当ARP协议被询问一个已知IP地址节点的MAC地址时,先在ARP缓存中查看,若存在,就直接返回与之对应的MAC地址,若不存在,则发送ARP请求包向局域网查询。
ARP高速缓存分动态与静态项目,动态项目随着时间自动添加与删除,每个动态ARP缓存项都设置TTL时间,当TTL时间为0时,此项目就从表中删除,Window下TTL一般不超过10min。静态ARP缓存是永久性的,可以使用TCP/IP工具来手动添加与删除。通常用来禁止节点发送对常用的IP地址(如路由器和服务器的IP地址)的ARP清求,防止ARP攻击。
c)工作流程
如果目的IP与源IP在同一网段:
当ARP高速缓存表中存在目的IP对应的MAC地址,则通过send函数(参数为目的IP及目的MAC),将数据送至数据链路层,完成以太网帧的封装,最后通过物理层发送出去。
当ARP高速缓存表中不存在目的IP对应的MAC地址,网络层将数据报缓存下来,发送ARP请求包请求目的IP的MAC地址,收到ARP应答之后,将目的IP与目的MAC地址的对应关系缓存在ARP高速缓存中,然后通过send函数将数据送至数据链路层,完成以太网帧的封装,最后通过物理层发送出去。
如果目的IP与源IP不在同一个网段(这种情况居多):
首先就需要将数据包发送给默认网关,至于如何找到网关的MAC地址就是重复上文所提到的流程。下面举个例子来说明这种情况的整个流程:
假设一个数据包(X)由南昌的一台主机A发往北京的一台主机B,这两台主机之间是通过许多中间节点(如网关、路由等)连接起来的。我们现在假设传输过程中需要经过2个节点1、2。
主机A在数据包X发出前,先发送一个ARP请求包,找到到达主机B所必须途经的第一个节点1的MAC地址,然后将IP_A、IP_B、MAC_A、MAC_1封装在数据包中传输至节点1。
再通过ARP请求包,找到第二个节点2的MAC地址,同样将然后将IP_A、IP_B、MAC_A、MAC_2封装在数据包中传输至节点2。
依旧通过ARP请求包,找到与IP_B相对应的物理地址MAC_B,最后将数据包传至主机B。
在传输过程中IP_A、IP_B、MAC_A不变,而中间节点的MAC地址通过ARP在不断改变,直到找到目的地址MAC_B。其示意图如下所示:
4、传输层
在介绍协议前,我们先要讲清楚端口是什么?
假设现在数据已经发送到我们的电脑了,那么电脑上的开启了n个进程,那么这个数据到底是发送给谁的呢?这就要通过端口号来区分了。
在TCP/IP协议中,端口号的范围从0~65535,其中0~1023是公认端口号,一般固定分配给一些服务,比如用于浏览网页服务的80端口,用FTP服务的21端口,用于telnet的23端口。
动态端口号的范围从1023~65535,这些端口号一般不固定分配给某个服务,只要运行程序向系统提出访问网络的申请,那么系统就可以从这些端口号中分配一个供该程序使用,当关闭程序进程后,会释放所占用端口号。Modbus的默认端口号为502。
A、协议包头
TCP的协议包头结构图如下所示:
源端口号(16位)与目的端口号(16位):即数据传输发起者的端口号与数据传输接收者端口号。
序号(32位):由接收端使用,TCP会按这个顺序号将分段后的报文重新拼接成最初的形式。
确认序号(32位):由接收端使用,是接收端期望收到发送端下一个报文段的顺序号,因此确认序号,应是上次已成功收到的序号+1。
首部长度(4位):用来描述TCP包头的长度,该部分的单位为32bit(4个字节)。即本区域的值=TCP头部长度(单位为bit)/32。TCP包头的最小长度为20字节,最大为60字节。
保留(6位):无意义,均填充为0。
TCP标志位(6位):高位到地位依次为URG(紧急;置1时,表示报文段中有紧急数据,应尽快传送)、ACK(确认;置1时,确认序号有效)、PSH(推送;置1时,数据报一到便可送往应用程序,不必等缓存区满)、RST(复位;置1时,表明连接出现差错,需释放连接再重新建立)、SYN(同步;置1时,用来发起一个连接)、FIN(终止;置1时,用于释放连接)。
窗口大小(16位):用来进行流量控制,告诉对方TCP接收缓冲区还能容纳多少字节的数据。通过声明窗口大小可控制起始于确认序号的数据段的大小。窗口最大为65535字节。
校验和(16位):和IP校验和的计算方法相同,但计算范围不一样。IP校验和只计算IP包头,而TCP校验和包括伪首部(源IP地址、目的IP地址、保留字节、传输层协议号、TCP报文长度)、TCP首部、TCP数据。
紧急指针(16位):当URG标志置1时,紧急指针才有效,否则将被填充。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
选项(可变长度):最常见的可选字段时最长报文大小,又称为MSS。每个连接方通常都在通信的第一个报文段指明这个选项,它指明本端所能接收的最大长度的报文段,通常设置为1460字节。默认为536字节。
B、三次握手与四次挥手
a)三次握手
首先客户端向服务器申请建立TCP连接,向服务器端发送一个SYN报文,作为第一次握手。客户端将这段连接的Seq(序号)设定为随机数X。【第一次握手】
当服务器端收到SYN报文后,会给客户端发送一个报文。报文中ACK置1,SYN置1,Seq为随机数Y,确认序号为X+1。【第二次握手】
客户端收到ACK置1、SYN置1、Seq为Y、确认序号为X+1的报文,客户端再次发送ACK置1、SYN置0、Seq为X+1、确认序号为Y+1的报文,服务器收到ACK置1且确认序号为Y+1的报文后,则三次握手完毕。【第三次握手】
至此,TCP连接建立完毕,可以开始正常传输数据了。
其三次握手示意图如下所示,大家可以对照上面的说明,在走一遍流程。
说明:
为什么要建立三次握手?如果只有两次握手会出现什么异常情况?
目的防止失效的连接请求报文被服务器接收从而产生错误,如果只有两次握手,则服务器收到连接请求后就会进入连接状态。当发生网络拥塞时,客户端发送的连接请求迟迟未到服务器端,那么客户端会进行超时重发,如果服务器正确接收并确认应答,开始通信,通信完毕后释放连接。若此时那个失效的连接请求抵达了服务器端,那么服务器端就会进入连接状态,等待或主动发送数据,而此时客户端已经进入CLOSED状态,服务器会一直等待下去,浪费服务器资源。
b)四次挥手
终结连接可由双方任意一方发起,本文以客户端发起为例。
首先客户端向服务器端发送一个FIN置1,Seq为U的报文,用于向服务器端请求释放。此时客户端进入FIN-WAIT1状态,说明客户端无数据发送给服务器端,但是服务器端还可以继续发送数据。【第一次挥手】
然后服务器端收到上述报文后,会通知应用程序,告诉它客户端向服务器端这个方向的连接已经释放。此时服务器端进入CLOSE-WAIT状态,并向客户端发送ACK=1,Seq=V,ack=U+1的报文。【第二次挥手】
客户端收到上述报文后,进入FIN-WAIT2状态,等待服务器端发送释放请求。这时,服务器端依旧可以继续发送数据。
当服务器端向客户端发完所有数据后,向A发送连接释放请求报文,其中FIN置1,ACK置1,Seq=W,ack=U+1。服务器端进入LAST-ACK状态。【第三次挥手】
客户端收到释放请求后,向服务器端发送确认报文,其中ACK=1,Seq=U+1,确认序号=W+1,此时进入TIME-WAIT状态。该状态持续2MSL时间,若在该时间段没有服务器端的重发请求的话,就进入CLOSED状态。当服务器端收到确认报文后,也进入CLOSED状态。【第四次挥手】
其四次挥手示意图如下所示,大家可以对照上面的说明,在走一遍流程。
说明:
为什么四次挥手结束了,A要先进入TIME-WAIT状态,待会2MSL时间后才进入结束状态?
为了保证服务器端能够收到客户端的确认应答,若客户端发完确认后直接进入CLOSED状态,那么如果客户端发出的应答丢失,服务器端将重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,那么服务器端永远无法正常关闭。
C、TCP的分段、重组与重发
a)分段
当TCP报文大于MSS(最长报文大小)时,TCP协议会将TCP报文分段发送。MSS(1460字节)一般是小于MTU(1500字节)的,所以当采用传输层TCP时,仅在运输层分段,网络层不会进行分片。
在TCP包头无可选项时,TCP报文的数据部分将按1460字节每段进行分段,完毕后加上TCP包头(20字节)与IP包头(20字节),凑成1500字节,刚好满足MTU,进行发送。
b)重组
首先每到来一个TCP数据包,先检查该数据包的源IP地址、目的IP地址、源端口号、目的端口号,取出来在重装链表的纵向中寻找有没有与其相匹配的链表存在。如果有则放入与其纵向参数(源IP地址、目的IP地址、源端口号、目的端口号)一致的链表内,放入链表时,先依旧报文的序号放在链表的合适位置中。如果无,则新建一个链表。
当收到报文为完全重复报文(seq1<=seq2且seq1+len1>=seq2+len2),丢弃该报文。
当收到报文为部分重复报文(seq1<=seq2且seq1+len1<seq2+len2),将计算重复字节数,依此截取报文中的新数据,重新设置该报文的序号及长度,追加至链表内的合适位置。
当为提前到达报文(seq2>seq1+len1),将此报文放在失序报文队列中存储起来,以备后续重组。
c)重发
当发送端收到3个相同的确认序号(快速重传)或者重发定时器超时(超过一定时间未收到新的确认序号)重发该以该确认序号为序号的数据包。
5、应用层
A、协议结构
其实到了应用层,反而就简单了。Modbus TCP/IP与Modbus RTU不同之处就是7个字节的报文头(RTU中的从机地址作为单元标识符进入报文头),数据部分的语法完全和RTU一样。
数据链路层的CRC校验与传输层的校验和已经对应用层报文进行了校验,因此RTU中原有的CRC校验取消。
Modbus TCP/IP的协议结构如下所示:
事务处理标识符(2字节):MODBUS请求和响应传输过程中序列号,此字段应答报文与请求报文保持一致。
协议标识符(2字节):0表示modbus,1表示UNI-TE协议,一般默认为0x0000,此字段应答报文与请求报文保持一致。
长度(2字节):用来表示接下来的数据长度(包含单元标识符及数据域),单位为字节。
单元标识符(1字节):用以标识在串行线或网络上的远程服务端的地址,通常情况下意义不大,被IP地址取代。但当TCP与RTU之间进行协议转换时,该数据就是RTU中的地址码。
注意:
1、在Modbus TCP/IP中,服务器是从机,而客户端是主机。
2、除非设备作为modbus网关服务器挂接多个RTU设备时,数值为01-FF,否则一般为00。
3、事务处理标识符一般默认为0x0000
B、示例
将Modbus RTU改写成Modbus TCP/IP形式。
Modbus RTU:01 03 01 8E 00 04 25 DE
Modbus TCP/IP:00 00 00 00 00 06 01 03 01 8E 00 04
两者含义是一样的,就是从地址码为01的模块的0x018E寄存器地址开始读4个寄存器。
至此,modbus协议家族就都介绍完毕了。能看到这里真得不容易,谢谢大家!