李 涛,韩 鹏,侯冠东,2,詹佳缘
(1.西北工业大学 航海学院,西安 710072; 2.北京展讯高科通信技术有限公司,北京 100011)
以太网作为目前一种通用的局域网通信协议标准[1],具有通信可靠、传输速度快、远距离传输和适配多种传输介质等优点[2]。而TCP/IP协议具有开放的协议标准,不依赖固定的硬件或软件系统,可以将TCP/IP协议集成于不同的网络标准中,是当前应用最广泛的网络通信协议[3-4]之一。在TCP/IP协议簇中完成数据传输与控制的协议主要有TCP[5]和UDP[6-7],TCP协议可靠性和安全性较高,但由于传输过程冗杂,因此速率相对较低;UDP协议由于其面向无连接、程序机构较简单,因此具有较高的传输速率,但存在不可靠、不稳定的弊端[8]。目前在国内外研究成果中,有研究人员提出将TCP和UDP优点相结合形成RUDP草案[9],但是对RUDP可靠传输机制中最重要的确认与重传以及流量控制技术却没有详细讨论,人们在应用RUDP协议时只能自行设计这些机制,虽然已经有部分自行设计得到了成功应用,但是协议大多使用软件编程的思想实现,对于硬件实现不太适用,此外,直接借用TCP所有的可靠传输机制,用硬件实现过于复杂[10]。基于此,本文通过分析TCP 协议和可靠UDP协议,提出一种优化的可靠 UDP 协议 ORUDP,以实现网络数据包在传输过程中保证数据可靠性传输的功能,同时提高传输速率。
TCP协议是一种基于流的、面向连接的可靠数据传输协议[11],能实现通信双方无差错地发送和接收网络数据,在传输过程中不会出现数据丢包、数据错包以及数据包重复、乱序和数据较多造成的网络拥塞等现象[12]。常见的可靠机制如握手连接、滑动窗口、拥塞窗口、漏发重发、累积确认等机制虽实现了网络数据传输的可靠性,但这些机制增加了数据的复杂度和数据处理的工作量,会导致数据的传输效率变低,所以 TCP 协议主要用于对数据的可靠性要求比较高而对数据传输的效率要求一般的场合[13],其协议格式如图1所示。
图1 TCP协议格式
UDP即用户数据报协议,与TCP协议相比,UDP协议较为简单,它的特点是提供无连接、尽最大努力交付基于消息包的不可靠数据传输服务[14]。由于其无连接性,因此不需要设计建立连接与连接释放的功能,可以节省部分资源,此外它不提供可靠服务[15],故不需要维护待确认数据,进一步节约了资源,同时也节省了重传、等待确认的时间。因为UDP协议不提供流量控制,所以会节省用来控制流量的资源[16]。综上,UDP协议以损失可靠性为代价换来极高的传输效率[17]。UDP协议由源端口号、目的端口号、长度、校验和4个部分组成,协议格式如图2所示。
图2 UDP协议格式
在实际工程应用中,需要在传输过程中保证数据等可靠性传输功能,同时还要拥有较高的传输速率[18]。据此,本文依据RUDP草案,引入并改进TCP可靠机制,在原有的UDP 协议首部填加一些控制字段而形成一种面向连接的基于消息包的传输协议。在通信双方传输数据之前采用与TCP类似的建立连接机制,即三次握手建立连接,数据传输任务结束后双方独立关闭自己的传输通道,经过四次握手关闭连接;在可靠机制的设计中,采用累积确认机制,与停止等待协议相比,既可以保证数据传输的可靠性,又能节省发送等待确认的时间;引入重传机制,即只要接收方收到了非期望序号的包文,立即给接收方提交重传请求包,并把期望的序列号发送给发送方,发送方接收到重传请求包后立刻丢掉当前正在传输的数据包,从出错的包文处重新开始发送,而不是全部发送;选用比较节约资源的基于GBN的滑动控制机制并对其进行适当改进作为流量控制机制;采用乒乓缓存的机制作为双队列加速机制。据此,设计方案在UDP协议高效传输的基础上实现其可靠性。
2.1.1 ORUDP层级结构
ORUDP协议是在原有的 UDP 协议首部填加一些控制字段形成的一种面向连接、基于消息包的传输协议,从网络参考模型的角度来看同样是介于应用层和UDP传输协议层之间的一层,其层级结构如图3所示,它的存在只是为了增加UDP协议的可靠性。
图3 ORUDP层级结构
2.1.2 ORUDP格式与字段含义
ORUDP各个字段的含义如下:
1)16位端口号:占用4 Byte,前两个字节为源端口号,后两个字节为目的端口号,用来区分通信双方的不同进程。
2)16位包文长度:占用2 Byte,用来表示 ORUDP 数据包文的字节长度,包括首部和应用数据。该字段最小值为18,即 ORUDP的首部字节长度。
3)16位校验和:该字段填充包文的校验和,运算方式为二进制反码求和,参与运算的数据不仅包括首部和数据,而且还要添加 12 Byte的伪首部参与运算,校验和是用来保证数据传输的正确性,ORUDP的可靠传输机制主要解决丢包、乱序、重复问题。
ORUDP可以发送两种包文,一种是用来保证可靠传输的控制包文,另一种是需要传输的数据包文,当各个控制字段都为0时代表普通数据包,否则即为控制包文,格式如图4所示。
图4 控制包文格式
ORUDP各个字段的含义如下:
1)1位的标志位 SYN:该标志位在建立连接时使用,当 SYN为1且ACK 为0时,代表请求连接包,若另一方同意连接,则把SYN和ACK同时置1,代表一个连接应答包,当SYN和FIN标志位一起为1时代表请求关闭包。
2)1位的标志位 ACK:当 ACK 值为1时表明这是一个应答包,本标志位与其他标志位配合使用,如当SYN和ACK都置1时代表这是一个连接应答包,当FIN和ACK都置1时代表这是一个关闭应答包,仅有为1时代表数据确认包。
3)1位的标志位 FIN:该标志位在关闭连接时使用,当FIN为1且ACK 为0 时,代表请求关闭包,若另一方同意关闭,则把FIN和ACK同时置1,代表一个关闭应答包。
4)1位的标志位 RETR:当RETR为1时表明当前是一个重发请求包,用于重传机制,发送方收到重传请求后会从发送队列里面重新传送数据包。
5)1位的标志位ACKREQ:当ACKREQ为1时表明发送方已经连续发送了一批数据包并且需要接收方及时确认。
6)1位的标志位TES:TES用在发送方和接收方建立连接后开始传输数据之前,发送方探测接收方缓存大小。
7)16位的序列号:该字段用来标记发送的数据包的顺序号,接收方期望包寄存器与之比对产生相应的动作。
8)16位的确认/重发序号:该字段用来填充需要确认的 ORUDP 包序号或需要重新发送的 ORUDP 包的序号。
9)16位的重传地址:该字段用来填充需要重传的包在发送方发送队列里面的位置,和重传请求一起使用。
10)16位窗口大小:由于ORUDP采用了改进的滑动窗协议来进行流量控制,因此要增加16位的窗口大小来进行流量控制。
2.1.3 ORUDP序列号
应用层的数据需要经过ORUDP协议打包处理。在打包过程中会为每一个包文添加一个序列号,序列号的顺序与应用层传送数据顺序一致。包文序列号的初始值为0,每发送一个数据包,包文的序号就自动加 1。 ORUDP协议的序列号机制是为了保证接收端可以按序接收,当发生乱序时及时重传。
ORUDP在通信双方传输数据之前采用与TCP类似的建立连接机制。在开始传输数据之前,发送方和接收方必须通过三次握手建立连接。数据传输任务结束后双方都要独立关闭自己的传输通道,只有经过四次握手才能彻底关闭连接,具体过程如图5所示。
图5 ORUDP连接与释放过程
2.3.1 ORUDP确认机制
ORUDP协议采用改进的累积确认机制,在该机制下接收方收到一批正确的数据包才会发送确认消息,与停止等待协议相比,既可以保证数据传输的可靠性,又能节省发送等待确认及多个确认的时间。
累积确认机制通常是在接收方设置一个累积计数器用来统计正确接收的数据包的个数,接收方正确接收N包数据后才会向发送方发送数据确认包,发送方收到数据确认包后把已经发送的N包数据从发送队列中清除掉,再从发送缓存区装入N个新的数据包继续发送[11]。该确认机制的优点是减少接收方发送数据确认包的频率,在一定程度上会减少网络的拥塞状况。但该机制容易发生数据传输不完整的情况,即当发送方需要发送的数据量较小不能往队列里面装够N包数据,或者在发送大量数据时剩余的最后一点数据同样不能向队列里装够N包数据,发送方一直不能将这些数据发送出去。
为解决这个问题,本文的确认时机由发送方控制,在一定条件下发送方会主动发送请求确认包,接收方不需要对按序接收的数据包进行统计,一旦收到发送方发来的请求确认包,会发送数据确认包。在这种机制下,发送时机的选择特别重要,一般的RUDP协议发送时机选在发送队列中装满时,本文除采用这种时机外,还增加了一种时机,即发送的数据量较少或者发送剩余的少量数据时,在这些数据都装到发送队列后等待一定时间,如果应用层的缓存区没有新的数据被送入立刻启动发送进程,在被发送到队列中的最后一包数据时发请求确认包。
2.3.2 ORUDP重传机制
在采用基于GBN的滑动窗口机制中,只有发送方的超时定时器溢出时才会重传所有已经发送但还未收到确认的数据包,这种重传机制在与本文的确认机制一起使用时会出现2个问题:
1)增加发送方重传等待时间,假设发送方依次发送了1号~N号共N个数据包,在发送第N号包时把请求确认标志位置高,代表这是一个请求确认包,如果第N-1包在传输过程中丢失,当接收方接到未按序到达的N号数据包时会发应答包。且应答包应答号为N-2,发送方收到应答包后如果重传定时器没有溢出,依然不会立刻重传第N-1号数据包而且重传定时器会重新记时。
2)容易引起不必要的重传,还是在上述情况下,如果丢失的是第N包数据,那么接收方会因为收不到请求确认包时而不发送数据确认包时,发送方在重传定时器溢出后会重传N-1包数据。
为解决上述问题,本文采用立刻重传的机制,只要接收方收到了非期望序号的包文,立刻给接收方提交重传请求包,并把期望的序列号发送给发送方,发送方接收到重传请求包后立刻丢掉当前正在传输的数据包,从出错的包文处重新开始发送,而不是全部发送。
2.3.3 ORUDP定时器
ORUDP会在建立连接和连接释放、发送方发出请求确认包、发送方发出窗口探测包、接收方发出重传请求包时这4种情况打开重传定时器,如图6
所示。发送方发出请求连接包需要接收方回复一个连接应答包,发送方会打开重传定时器,在定时时间内如果没有收到连接应答包,发送方会重新发送请求连接包,引入定时重传机制确保通信双方在网络正常的情况下建立连接。只要发送方或接收方提交了请求关闭包,请求关闭的一方就打开重传定时器,定时重传机制和建立连接的情况类似,这里不再详述。
图6 4种定时器工作原理
虽然RUDP草案中并没有描述如何去控制流量,但如果不对流量进行控制很容易引起接收方缓冲区溢出。此外,在网络环境不佳时容易引发网络拥塞导致网络崩溃。考虑窗口控制机制的复杂性和硬件耗费,本文选用比较节约资源的基于GBN的改进滑动控制机制[19]。
滑动窗口的状态由P1、P2、P3这3个指针控制,在TCP协议中P1、P3只有在发送方收到数据确认包时才更新,在本文的设计中接收方不仅会发送数据确认包而且还会发送重传请求包,此时也会更新窗口状态,图7所示为假设发送方收到重传请求且重传的包号为31并且通知窗口为20,说明接收方已正确接收前30包的数据,这时停止发送即P2停止不动,将P1指向31,P3指向51,P2=P3就停止发送,只有收到数据确认包后才能继续发送新的数据包。
图7 滑动窗口示意图
应用进程一般用FIFO来缓存数据,但是在FIFO中的数据一旦读出就不再保存,可靠传输要求发送出去的数据必须等到相应的确认包后才能丢失,故而ORUDP使用队列来缓存应用层的数据。在软件实现网络协议栈时,数据的发送和缓存不能同时进行,而在使用硬件实现时可以利用并行计算的特点在发送数据时缓存新的待发数据,由于ORUDP是基于包传输的,因此在进行窗口滑动时要调整3个指针的位置,使其都指向数据包的首地址,这时不能对窗口进行操作,故而会带来一些等待时间,为了消除这些时间,ORUDP采用乒乓缓存的机制将发送队列拆成2个队列同时操作,如图8所示,一个队列充当发送队列在滑动窗等可靠机制的管理下进行数据发送,另一个队列充当装载队列装载应用进程缓存的数据,发送队列在调整窗口状态时不影响装载队列的工作。
图8 乒乓缓存机制
ORUDP通过握手连接、序列号、确认号、滑动窗口、双队列等协同工作确保数据高效可靠传输。在建立连接后收发双方各自启动自己的接收和发送进程,发送方和接收方的工作流程如图9和图10所示。
图9 发送流程
图10 接收流程
在建立连接之后发送方处于空闲状态,如果应用进程需要发送数据,首先会把数据发送到自己的FIFO缓冲区当中,后续的发送任务就交给ORUDP处理。处理过程主要由滑动窗口管理及双队列加速机制实现。
依据混合网络参考模型,结合FPGA并行处理的特点,本文采用分层设计的思想将整个ORUDP协议栈从上到下分成可靠传输层、传输层、网络层、链路层4个部分独立实现,系统结构框架如图11所示。
图11 系统结构框架
可靠传输是协议栈中的重点,这一层引入了各种可靠机制来保证数据可靠传输,为便于实现采用模块化的思想,将该层拆成6个功能各异的小模块加以实现,具体的划分结果如图12所示。
图12 可靠传输层划分结果
3.2.1 连接管理模块设计
连接管理模块包括客户端/服务器连接管理模块,本模块的作用是负责 ORUDP通信过程的连接管理,作为服务器要能响应客户端的连接请求,作为客户端在需要数据传输之前向服务器提交连接请求,只有成功建立连接双方才能正常通信。
依据ORUDP建立连接和连接断开过程,设计客户端连接管理模块有限状态机如图13所示,功能为进行有传输任务时客户端的连接请求处理。对应服务器连接管理模块工作流程如图14所示。
图13 客户端连接管理模块状态机
图14 服务器连接管理模块状态机
3.2.2 数据接收模块设计
数据接收模块是可靠传输层 ORUDP 的解包模块,本模块的作用有两种,一种是识别不同的包文类型,另一种是对普通的数据包文进行拆解交付到应用层的接收 FIFO 中。依据功能的不同将 ORUDP 包文分成两种,一种是与连接管理有关控制包文,另一种是与数据传输有关普通的包文。控制包文包括请求连接包、连接应答包、请求关闭包、关闭应答包和建立应答包;普通包文包括窗口探测包、数据确认包、重传请求包、请求确认包和普通数据包。客户端可以主动发起连接而服务器只能被动响应连接,因此客户端和服务器的数据接收模块略有不同,具体表现在只有客户端可以发送请求连接包和建立应答包,只有服务器可以发送连接应答包。由前述可知,ORUDP 是靠其首部的前 6 位来区分包文类型的,将其定义为命令字段,其真值表如表1所示。
表1 命令字段真值表
ORUDP接收普通包文的前提条件是必须处于连接已经建立的状态或者半关闭状态(只能接收不能发送普通包文),在需要向对方回复普通包文时产生相关控制信号给命令发送模块,由命令发送模块封装成可靠传输层的包文。
3.2.3 命令发送模块设计
命令发送模块的作用是解析接收模块和连接管理模块发来的控制信息,根据输入信息产生可靠传输层 ORUDP 控制包文,该模块可以产生的包文有请求连接包、连接应答包、请求关闭包、关闭应答包、建立应答包。普通包文包括窗口探测包、数据确认包、重传请求包,不能发普通数据包和请求确认包,普通数据包不携带任何控制信息,而其他包文都有控制信息,因此不宜在本模块中封装,其状态转移示意图如图15所示。
图15 命令发送模块状态转移示意图
3.2.4 数据管理模块设计
数据管理模块的作用是在双队列滑动窗等机制的作用下,将应用进程发送至 FIFO中的数据高效可靠地发送给数据打包模块,可靠传输层中所有的可靠机制都在这一模块实现,其他和数据传输有关的模块只是把本模块流出的数据包打包成ORUDP 格式的包文,该模块的工作流程与状态转移、滑动窗口的滑动机制见第2节。
3.2.5 数据打包模块设计
数据打包模块的作用是将数据管理模块的包文进行缓存与打包,为了保证包文的完整性,即连续输出一包数据中间不会有缺失,该模块使用图16所示的双 FIFO 架构,其中,数据 FIFO缓存上级数据包,信息 FIFO统计完整包文的个数,当收到一包完整包文时就向信息 FIFO中写入数据,信息 FIFO中有数据代表FIFO 中有完整的包文,此时应该打包输出,打包过程和命令发送模块打包过程类似,此处不再详述,为提高传输效率,可以去掉包头的 10个 0XFF,因为数据包长度足够,不必为了拼凑成以太网帧格式而添加额外数据,但本文为了测试方便与命令发送模块统一先添加10个字节。
图16 数据打包模块
3.2.6 轮转调度模块设计
轮转调度模块的作用是轮流输出命令发送模块和数据打包模块输出的包文,因为 FPGA 内部是并行处理的,命令发送模块和数据打包模块同时工作,但是传输线上的包文是逐个传输的,为防止传输数据包时丢失命令包,特设计该模块同时缓存命令数据和普通数据,命令包的优先级大于数据包。
经过上文的设计,本文硬件协议的各个模块都得以实现,为了让其正常工作还需要将各个模块相互连接,确定信号的流向。在FPGA中各个模块相连的过程与实际电路的布线类似,最终的互连结果如图17所示,因模块间的具体连线过于复杂,这里仅给出信号流向示意图。
图17 信号流向示意图
本节将使用搭载Altera公司Cyclone Ⅳ系列FPGA以及千兆网口的实验开发平台分别作为客户端和服务器,为两块FPGA芯片装载客户端和服务器逻辑程序,借助SignalTab逻辑分析仪,捕获芯片内部的实时数据进行实验验证。
搭建好的ORUDP测试系统如图18所示。客户端选用搭载EP4CE15F23C8以及RTL8211网络PHY芯片RJ45接口的实验平台如图18中的A所示,服务器选用搭载EP4CE10F17C8以及RTL8211网络PHY芯片RJ45接口的实验平台如图18中的B所示,两者通过网线直接连接。
图18 ORUDP测试系统
在实验室环境下只能近距离传输,网络上不会有路由,在这种理想环境下很难出现数据包丢失的情况,此处人为制造丢包条件,屏蔽接收方数据确认的功能,屏蔽以后重新下载到服务器中,测试客户端作为发送方服务器屏蔽接收方的超时与错误重传功能。客户端发送完0号~6号数据包文以后进入等待状态,由于接收方不会回应数据确认包,超时定时器一定会溢出并重新发送未被确认的数据包文,如图19所示,发送方重传的数据包不是接收方期望的,接收方发送重传请求,发送方收到重传请求重新发送要求重传的数据包,如图20所示。
图19 数据包的重新发送
图20 进入等待状态的数据包
本文选用的测量传输速率的方法是计算传输定量数据包所消耗的时间,从而算出传输速率,在实际的测量过程中有很多不确定因素,如环境的温度、芯片的工作时长等都会对测试结果造成一定影响,因此进行了多次测量,将所有测量结果记录并求平均。此外,单次测量数据量不能太小,否则时间测量的结果波动较大,降低测量结果的准确性。将客户端和服务器的双队列大小都设置成35 840 bit,每次传输1 536 Mbit大小的数据。传输完毕后就停止测试,记录传输时间,算出传输速率。为了避免偶然性,在4个不同的时间段内进行速度测试。表2是在4个不同时间段测试的结果。
表2 4个不同时间段传输速率
文献[20]使用RTL8211千兆网PHY芯片与FPGA设计的一种TCP硬件协议栈,采用FPGA为主控芯片、88E1111为物理层网卡芯片,在没有实现拥塞控制的情况下,实验室环境下最大传输速率为360 Mb/s。文献[21]设计增强型可靠UDP,并提出了一种补发机制,利用在发送端维护数据发送指针和数据补发指针,由补发指针来完成补发操作,发送端发出去的数据包也不需要接收端予以确认。应用于硬盘式高清数字机顶盒,在实验室环境下最大传输速率为300 Mb/s。文献[22]设计的基于TCP/IP的PET高速数据传输系统,使用KEK日本高能加速器研究机构设计的基于 FPGA 的TCP以太网协议栈 SiTCP,选用FPGA作为核心控制芯片,在实验室环境下最大传输速率为360 Mb/s。而本文实现的ORUDP网络协议栈传输速率可达440 Mb/s,性能优于一般的TCP硬件网络协议栈。
本文研究TCP/IP网络协议栈,依据RUDP草案,引入并改进TCP可靠机制,设计一种基于消息包、面向连接的高速可靠网络传输协议ORUDP。选择FPGA进行ORUDP协议栈的逻辑设计和实现,并设计窗口调整机制确保消息包的完整性,采用滑动窗口、双队列乒乓等机制保证消息包的可靠高速传输。在ORUDP网络协议栈上的测试结果表明,该协议具有较快的传输速度。本文设计的ORUDP应用场景较为简单,仅考虑 3 台功能计算机组网的情况,拥塞控制机制较弱,下一步将引入 TCP 慢启动、快重传等拥塞控制机制,运用FPGA芯片将GBN机制替换为传输效率更高的SR机制,从而提高传输速率。