高性能路由器硬件的关键技术研究( 二 )


由文献[4]分析可知,可以使用内核kiobuf机制,他能提供从内核空间对用户内存的直接访问 。内核kiobuf机制的设计初衷就是为了便于将用户空间的缓冲区映射到内核 。使用他能够获得数据的页面起始位置、页数和偏移量等具体参数,因此可在内核空间对用户态申请的内存进行操作 。
首先分配一个内核I/O向量(kiovec)来产生kiobuf,使用函数如图2所示 。
 
然后再对其进行初始化,如图3所示 。
 
最后,将通过ioctl传入的用户空间指针ifru_data映射 到内核态,使用函数map_user_kiobuf,如图4所示 。
 
这样就完成了将指针由用户空间映射到内核空间的过程,实现了从虚拟地址向物理地址的转换 。
至此,内核空间与用户空间的内存映射问题得到了很好的解决 。通过解决内存地址映射的问题,内部通信和虚拟驱动之间就可以只传递数据指针,大大提高了模块的运行效率 。
2.3 基于分隔符的TCP实时传输方法
2.3.1 Nagle算法的弊端
糊涂窗口综合症(Silly WindowSyndrome)的出现使网络开销过大,从而造成TCP性能变坏 。根据文献[5]所述,糊涂窗口综合症的解决方法就是采用文献[6]中所建议的Nagle算法 。但是在实际应用时发现,Nagle算法的不足之处主要有2点:
(1)在限制数据报头部信息消耗的带宽总量的同时,是以牺牲网络延迟为代价的 。
(2)在发送方的缓冲区中,应用程序发送的数据包发生了粘滞的现象,即发送的若干数据包到接收方接收时变成一包,分不出各个包的界线 。
前者因为数据被排队而不是立即发送的,因此不适用于需要快速响应时间的系统 。后者则会影响到接收方的数据处理的准确性 。第一种不足可以通过使用PUSH标记来实现,发送方假如使用了该标志,会立即将缓冲区中的数据发送出去 。对于第二个问题,解决起来就比较复杂,因为出现数据包粘滞现象的原因既可能由发送方造成,也可能由接收方造成 。
2.3.2 基于分隔符的TCP实时传输方法
采用了基于分隔符的TCP实时传输方法来解决包粘滞问题 。该方法在应用层数据包的起始部分附加上有特定格式的分隔符和数据长度域,其中分隔符用于界定数据包之间的界限,长度域则用于表示该数据包的实际长度 。
首先,所有经内部通信模块传输的数据,都需要进行一次内部固定格式的封装 。封装后数据包的包头,是由内部通信模块自定义的,起始位置是分隔符和长度域 。其次,接收方按照内部通信模块的自定义的包结构,接收后对数据流进行预处理,还原成为应用程序可正确识别的数据包 。预处理的原理如下:先查找包头中的分隔符,他标识着一个数据包的开始;接下来的域表示的是实际数据包的长度len,取出紧跟在包头后的长度为len的那段数据,这就是需要应用程序处理的数据包 。
包粘滞的情况具体可细分为3大类,这里均以2个应用程序数据包粘滞成一段的情况为例,如图5~图9所示,当应用程序数据包个数为n时,可采用类似的方法进行处理 。
 
 
 
 
第1类,粘滞数据是由完整的数据包组成的,如图5所示 。这种情况的处理非常简单,按分隔符找到数据包的起始位置,再根据数据长度取出应用程序数据即可 。
第2类,粘滞数据是由完整数据包和应用程序数据残缺的数据包组成,如图6和图7所示 。处理时,需要对残缺数据包2的应用程序数据部分进行保存,内部通信包头的数据长度域也要记录下来,以便下次接收时知道应用程序数据剩余部分的长度 。再次收到数据时,就根据剩余长度取出一段数据,与上次保存的应用程序数据合为一个完整的数据包 。

推荐阅读