您当前的位置:五五电子网电子知识电子知识资料网络技术采用对Windows TCP/IP协议栈进行一种简化设计 正文
采用对Windows TCP/IP协议栈进行一种简化设计

采用对Windows TCP/IP协议栈进行一种简化设计

点击数:7777 次   录入时间:03-04 11:43:36   整理:http://www.55dianzi.com   网络技术

   为了让Windows下的网络数据快速发送与接收,提高实时性能,采用对Windows TCP/IP协议栈进行一种简化设计,通过利用Windows提供的用户与设备对象的交互,减少Windows从用户态到内核态的分层,对Socket层进行简单的封装,并且利用零拷贝技术减少数据的拷贝次数以及设置多级优先级队列使数据按照优先级发送,从而使数据达到快速发送和接收的目的。实验结果验证了这种方法能达到预期效果。

    随着现代信息技术的进一步发展,对信息传递的速度及对大信息量的传输都有进一步需求,在这样的情况下,无论是对于硬件要求还是软件方面的要求都在提升。而在相同的硬件条件下,如何提高通信的速度、实时性能,软件的优劣在很大程度上影响着这些方面。由于Windo ws的广泛使用和其方便完善的网络结构的支持,针对Windows的网络开发不断增加,然而由于Windows系统为了包容多种协议以及Windows分层驱动的特点,导致数据从用户应用程序到网卡经过的驱动层数很多,势必导致数据的延迟增加,这对那些要求通信实时性能较高的系统来说是无法容忍的。所以研究Windows网络体系架构,对TCP/IP协议栈进行优化,使之适合于对于特定要求的系统,有很重要的研究意义和价值。

    1 Windows网络的多层结构

    如图1所示,标准的Windows网络体系结构的最底层是网卡,网卡通过NDIS与网卡(NIC)驱动程序通信,网卡驱动程序又通过NDIS与协议驱动程序通信。在NIC驱动程序和协议驱动程序之间还可以插进去一个中间驱动程序。在协议驱动程序的上边,是内核模式TDI客户驱动程序,通过TDI接口同协议驱动程序交互。再往上,则是用户模式的动态连接库(提供WIN32 NETAPI)及网络应用程序。

    a.JPG

    从图1中可以看出,用户层编写网络程序与其他主机进行通信,发送数据需要经过Sockets接口,TDI客户,TDI传输驱动接口,MDIS协议驱动(TCP/IP协议栈),NIC驱动程序,网卡,可以看出数据从用户提交给网卡的分层很多,Windows操作系统利用这种分层设计的方法,有诸多好处,开发人员可以只关注整个结构中的某一层;分层可以降低层与层之间的依赖,既可以良好地保证未来的可扩展,在复用性上也是很好的优势。但是分层结构也不可避免具有一些缺陷,一方面,分层过多会导致系统性能的下降,因为不采用分层结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成,其中需要处理数据通过各层的信息等操作,这些都降低了系统性能;另一方面是数据的拷贝次数增多,数据拷贝操作不单需要占用CPU时间片,同时也需要占用额外的内存带宽,这就增加了系统开销。这些消耗都会造成数据的时间延迟增加,这对于那些对实时性能有特别要求的而又需要利用Windows平台的系统来说,这是很难容忍的。

    2 对Windows TCP/IP协议栈的简化设计

    由于Windows网络结构分层较多,导致系统性能下降,网络数据的实时性能得不到体现,一种策略是简化现今Windows TCP/IP协议栈,减少分层;另一方面,利用零拷贝技术减少拷贝次数,减少系统性能消耗;可以采用多级优先级队列,让优先级较高的数据比优先级低的数据优先发送的基本策略,采用适当的调度算法进行处理。通过这几个方面的改进,可以一定程度上弥补Windows系统网络通信延迟较大的缺陷。

    b.JPG

    如图2所示,第1层为用户应用层;第2层是协议驱动,里面包括简化了的TCP/IP协议栈,只保留TCP,UDP,ARP,ICMP协议,并且对Wind ows中的AFD驱动模块简化,一些数据结构等就存放在设备扩展中;第3层是网卡驱动,第4层就是具体收发数据的网卡。在这几层里面第2层是最关键的部分,下面就具体如何设计进行比较详细的介绍。

    2.1 采用零拷贝技术

    简单一点来说.零拷贝就是一种避免CPU将数据从一块存储拷贝到另外一块存储的技术。零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据在存储器之间不必要的中间拷贝次数,从而有效地提高数据传输效率。而且,零拷贝技术减少了用户应用程序地址空间和操作系统内核地址空间之间因为上下文切换而带来的开销。在本文中对于TCP/IP协议栈,采用零拷贝技术,避免操作系统内核缓冲区之间进行数据拷贝操作,可以大大提高系统性能。

    在接收发送数据时,用NDIS中的NDIS_PACKET包描述符,包描述符中包含了数据包的总长度,指向第一个缓冲描述符NDIS_BUFFER的指针,缓冲描述符NDIS_BUFFER里面的Start Virtual Address才是指向真正的数据所在的首地址以及包含了此缓冲中的数据长度。利用这个NDIS_PACKET包描述符,可以实现无需对数据进行拷贝,只要获得包描述符即可。

    当用户数据提交给内核缓冲区时,采用直接I/O的方式,在内核中需要分配一个包首部的大小,用于TCP/IP协议层加上各层的首部,并且把该首部地址以及用户缓冲区地址用NDIS_PACKET包描述符封装。当发包线程把NDIS_PACKET包提交给协议栈处理时,不需要把包描述符中的数据拷贝到新的缓冲区中,可以直接利用NDIS提供的函数得到数据的首地址,以及数据包的总长度等。在协议栈中添加上各层首部以及其他操作后,就可以调用发包函数把NDIS_PACKET包描述符提交给网卡驱动,网卡驱动通过DMA把数据传送到网卡环形缓冲区中,再由网卡发送出去。

    反之,在收包时,网卡通过DMA把数据传输到内核缓冲区中,网卡驱动程序中依然用包描述符来指明数据的地址,大小等信息。在收包处理线程中,对数据包的拆包等操作,同样的不需要拷贝到新的缓冲区中,利用包描述符提供的包地址,大小等信息进行处理即可。

   



www.55dianzi.com

    2.2 设置多级优先级队列

    在网络数据传输中,由于有些紧急数据希望尽快发送出去提交给目的主机,而曰前的Windows系统网络传输机制并没有提供这样的功能。可以通过采用多级优先级队列的方式来达到一定的实时效果,比如对于紧急数据,可以设置最高优先级值,而一般数据就可以设置最低优先级值。在用户应用程序中,对发送函数进行封装,新的发送函数有个优先级参数,通过指明优先级参数值灵活处理数据,当提交给内核时,就按照优先级值放到相对应的优先级队列中。相应的在内核收包、发包缓冲区中,设置多级优先级队列,按照多级反馈队列调度算法进行处理,每个队列的优先级不同,并且每个队列的被处理的时间不同,各个队列的时间片是随着优先级的减少而增加的,优先级越高的队列中它的被线程处理的时间也就越短。比如紧急数据放到最高优先级队列中,迟缓的数据可以放到最低优先级队列中,在内核的发包线程中,首先判断最高优先级队列是否为空,不为空则优先发送该队列中的数据包,当该队列的时间用完,如果该队列还有包没有处理完,则把这些包链接到低一级的队列尾部,然后判断低一级优先级队列是否为空,重复以上的操作依次进行下去,当对最低优先级队列处理完后,再循环处理。如果线程在处理第i队列的数据时,这时候有新的用户数据进入到比i队列优先级高的j队列中,则线程处理完该数据就立即去处理j队列,这个可以用一个掩码mask,每一位标识一个队列,当队列不为空,则该标识位置为1,否则置为0。

    2.3 封装Socket层

    创建Socket套接字,就是打开设备对象(第一次是创建,之后就是打开),而打开设备对象就会创建一个内核文件对象,这个内核文件对象其实就可以映射创建的Socket套接字。对于打开设备对象,就可以用CreateFile()函数,并且把返回的句柄定义为Socekt句柄,之后的操作就可以直接用这个Socket句柄进行操作,如send()函数,可以用WriteFile()函数封装实现;Receive()函数可以用ReadFile()函数封装实现;bind()函数、setsockopt()函数、getsockopt()函数都可以通过DevICeIoControl()函数封装实现。为了真正实现打开设备等操作,需要在协议驱动程序中埘各个用户应用程序下达的IRP请求进行响应,用派遣函数就可以实现。在图2中,用户程序可以通过新封装好的Socket层,使用原来同样的Socket编程语句,这样使用户使用起来感觉没有差别,对用户是透明的。

[1] [2]  下一页


本文关键字:Windows  IP协议  网络技术电子知识资料 - 网络技术

《采用对Windows TCP/IP协议栈进行一种简化设计》相关文章>>>