對(duì)Windows TCP/IP協(xié)議棧的一種簡(jiǎn)化設(shè)計(jì)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
摘要:為了讓Windows下的網(wǎng)絡(luò)數(shù)據(jù)快速發(fā)送與接收,提高實(shí)時(shí)性能,采用對(duì)Windows TCP/IP協(xié)議棧進(jìn)行一種簡(jiǎn)化設(shè)計(jì),通過(guò)利用Windows提供的用戶(hù)與設(shè)備對(duì)象的交互,減少Windows從用戶(hù)態(tài)到內(nèi)核態(tài)的分層,對(duì)Socket層進(jìn)行簡(jiǎn)單的封裝,并且利用零拷貝技術(shù)減少數(shù)據(jù)的拷貝次數(shù)以及設(shè)置多級(jí)優(yōu)先級(jí)隊(duì)列使數(shù)據(jù)按照優(yōu)先級(jí)發(fā)送,從而使數(shù)據(jù)達(dá)到快速發(fā)送和接收的目的。實(shí)驗(yàn)結(jié)果驗(yàn)證了這種方法能達(dá)到預(yù)期效果。
關(guān)鍵詞:網(wǎng)絡(luò)體系結(jié)構(gòu);協(xié)議驅(qū)動(dòng);TCP/IP;零拷貝;優(yōu)先級(jí)隊(duì)列
隨著現(xiàn)代信息技術(shù)的進(jìn)一步發(fā)展,對(duì)信息傳遞的速度及對(duì)大信息量的傳輸都有進(jìn)一步需求,在這樣的情況下,無(wú)論是對(duì)于硬件要求還是軟件方面的要求都在提升。而在相同的硬件條件下,如何提高通信的速度、實(shí)時(shí)性能,軟件的優(yōu)劣在很大程度上影響著這些方面。由于Windo ws的廣泛使用和其方便完善的網(wǎng)絡(luò)結(jié)構(gòu)的支持,針對(duì)Windows的網(wǎng)絡(luò)開(kāi)發(fā)不斷增加,然而由于Windows系統(tǒng)為了包容多種協(xié)議以及Windows分層驅(qū)動(dòng)的特點(diǎn),導(dǎo)致數(shù)據(jù)從用戶(hù)應(yīng)用程序到網(wǎng)卡經(jīng)過(guò)的驅(qū)動(dòng)層數(shù)很多,勢(shì)必導(dǎo)致數(shù)據(jù)的延遲增加,這對(duì)那些要求通信實(shí)時(shí)性能較高的系統(tǒng)來(lái)說(shuō)是無(wú)法容忍的。所以研究Windows網(wǎng)絡(luò)體系架構(gòu),對(duì)TCP/IP協(xié)議棧進(jìn)行優(yōu)化,使之適合于對(duì)于特定要求的系統(tǒng),有很重要的研究意義和價(jià)值。
1 Windows網(wǎng)絡(luò)的多層結(jié)構(gòu)
如圖1所示,標(biāo)準(zhǔn)的Windows網(wǎng)絡(luò)體系結(jié)構(gòu)的最底層是網(wǎng)卡,網(wǎng)卡通過(guò)NDIS與網(wǎng)卡(NIC)驅(qū)動(dòng)程序通信,網(wǎng)卡驅(qū)動(dòng)程序又通過(guò)NDIS與協(xié)議驅(qū)動(dòng)程序通信。在NIC驅(qū)動(dòng)程序和協(xié)議驅(qū)動(dòng)程序之間還可以插進(jìn)去一個(gè)中間驅(qū)動(dòng)程序。在協(xié)議驅(qū)動(dòng)程序的上邊,是內(nèi)核模式TDI客戶(hù)驅(qū)動(dòng)程序,通過(guò)TDI接口同協(xié)議驅(qū)動(dòng)程序交互。再往上,則是用戶(hù)模式的動(dòng)態(tài)連接庫(kù)(提供WIN32 NETAPI)及網(wǎng)絡(luò)應(yīng)用程序。
從圖1中可以看出,用戶(hù)層編寫(xiě)網(wǎng)絡(luò)程序與其他主機(jī)進(jìn)行通信,發(fā)送數(shù)據(jù)需要經(jīng)過(guò)Sockets接口,TDI客戶(hù),TDI傳輸驅(qū)動(dòng)接口,MDIS協(xié)議驅(qū)動(dòng)(TCP/IP協(xié)議棧),NIC驅(qū)動(dòng)程序,網(wǎng)卡,可以看出數(shù)據(jù)從用戶(hù)提交給網(wǎng)卡的分層很多,Windows操作系統(tǒng)利用這種分層設(shè)計(jì)的方法,有諸多好處,開(kāi)發(fā)人員可以只關(guān)注整個(gè)結(jié)構(gòu)中的某一層;分層可以降低層與層之間的依賴(lài),既可以良好地保證未來(lái)的可擴(kuò)展,在復(fù)用性上也是很好的優(yōu)勢(shì)。但是分層結(jié)構(gòu)也不可避免具有一些缺陷,一方面,分層過(guò)多會(huì)導(dǎo)致系統(tǒng)性能的下降,因?yàn)椴徊捎梅謱咏Y(jié)構(gòu),很多業(yè)務(wù)可以直接造訪數(shù)據(jù)庫(kù),以此獲取相應(yīng)的數(shù)據(jù),如今卻必須通過(guò)中間層來(lái)完成,其中需要處理數(shù)據(jù)通過(guò)各層的信息等操作,這些都降低了系統(tǒng)性能;另一方面是數(shù)據(jù)的拷貝次數(shù)增多,數(shù)據(jù)拷貝操作不單需要占用CPU時(shí)間片,同時(shí)也需要占用額外的內(nèi)存帶寬,這就增加了系統(tǒng)開(kāi)銷(xiāo)。這些消耗都會(huì)造成數(shù)據(jù)的時(shí)間延遲增加,這對(duì)于那些對(duì)實(shí)時(shí)性能有特別要求的而又需要利用Windows平臺(tái)的系統(tǒng)來(lái)說(shuō),這是很難容忍的。
2 對(duì)Windows TCP/IP協(xié)議棧的簡(jiǎn)化設(shè)計(jì)
由于Windows網(wǎng)絡(luò)結(jié)構(gòu)分層較多,導(dǎo)致系統(tǒng)性能下降,網(wǎng)絡(luò)數(shù)據(jù)的實(shí)時(shí)性能得不到體現(xiàn),一種策略是簡(jiǎn)化現(xiàn)今Windows TCP/IP協(xié)議棧,減少分層;另一方面,利用零拷貝技術(shù)減少拷貝次數(shù),減少系統(tǒng)性能消耗;可以采用多級(jí)優(yōu)先級(jí)隊(duì)列,讓優(yōu)先級(jí)較高的數(shù)據(jù)比優(yōu)先級(jí)低的數(shù)據(jù)優(yōu)先發(fā)送的基本策略,采用適當(dāng)?shù)恼{(diào)度算法進(jìn)行處理。通過(guò)這幾個(gè)方面的改進(jìn),可以一定程度上彌補(bǔ)Windows系統(tǒng)網(wǎng)絡(luò)通信延遲較大的缺陷。
如圖2所示,第1層為用戶(hù)應(yīng)用層;第2層是協(xié)議驅(qū)動(dòng),里面包括簡(jiǎn)化了的TCP/IP協(xié)議棧,只保留TCP,UDP,ARP,ICMP協(xié)議,并且對(duì)Wind ows中的AFD驅(qū)動(dòng)模塊簡(jiǎn)化,一些數(shù)據(jù)結(jié)構(gòu)等就存放在設(shè)備擴(kuò)展中;第3層是網(wǎng)卡驅(qū)動(dòng),第4層就是具體收發(fā)數(shù)據(jù)的網(wǎng)卡。在這幾層里面第2層是最關(guān)鍵的部分,下面就具體如何設(shè)計(jì)進(jìn)行比較詳細(xì)的介紹。
2.1 采用零拷貝技術(shù)
簡(jiǎn)單一點(diǎn)來(lái)說(shuō).零拷貝就是一種避免CPU將數(shù)據(jù)從一塊存儲(chǔ)拷貝到另外一塊存儲(chǔ)的技術(shù)。零拷貝技術(shù)可以減少數(shù)據(jù)拷貝和共享總線操作的次數(shù),消除傳輸數(shù)據(jù)在存儲(chǔ)器之間不必要的中間拷貝次數(shù),從而有效地提高數(shù)據(jù)傳輸效率。而且,零拷貝技術(shù)減少了用戶(hù)應(yīng)用程序地址空間和操作系統(tǒng)內(nèi)核地址空間之間因?yàn)樯舷挛那袚Q而帶來(lái)的開(kāi)銷(xiāo)。在本文中對(duì)于TCP/IP協(xié)議棧,采用零拷貝技術(shù),避免操作系統(tǒng)內(nèi)核緩沖區(qū)之間進(jìn)行數(shù)據(jù)拷貝操作,可以大大提高系統(tǒng)性能。
在接收發(fā)送數(shù)據(jù)時(shí),用NDIS中的NDIS_PACKET包描述符,包描述符中包含了數(shù)據(jù)包的總長(zhǎng)度,指向第一個(gè)緩沖描述符NDIS_BUFFER的指針,緩沖描述符NDIS_BUFFER里面的Start Virtual Address才是指向真正的數(shù)據(jù)所在的首地址以及包含了此緩沖中的數(shù)據(jù)長(zhǎng)度。利用這個(gè)NDIS_PACKET包描述符,可以實(shí)現(xiàn)無(wú)需對(duì)數(shù)據(jù)進(jìn)行拷貝,只要獲得包描述符即可。
當(dāng)用戶(hù)數(shù)據(jù)提交給內(nèi)核緩沖區(qū)時(shí),采用直接I/O的方式,在內(nèi)核中需要分配一個(gè)包首部的大小,用于TCP/IP協(xié)議層加上各層的首部,并且把該首部地址以及用戶(hù)緩沖區(qū)地址用NDIS_PACKET包描述符封裝。當(dāng)發(fā)包線程把NDIS_PACKET包提交給協(xié)議棧處理時(shí),不需要把包描述符中的數(shù)據(jù)拷貝到新的緩沖區(qū)中,可以直接利用NDIS提供的函數(shù)得到數(shù)據(jù)的首地址,以及數(shù)據(jù)包的總長(zhǎng)度等。在協(xié)議棧中添加上各層首部以及其他操作后,就可以調(diào)用發(fā)包函數(shù)把NDIS_PACKET包描述符提交給網(wǎng)卡驅(qū)動(dòng),網(wǎng)卡驅(qū)動(dòng)通過(guò)DMA把數(shù)據(jù)傳送到網(wǎng)卡環(huán)形緩沖區(qū)中,再由網(wǎng)卡發(fā)送出去。
反之,在收包時(shí),網(wǎng)卡通過(guò)DMA把數(shù)據(jù)傳輸?shù)絻?nèi)核緩沖區(qū)中,網(wǎng)卡驅(qū)動(dòng)程序中依然用包描述符來(lái)指明數(shù)據(jù)的地址,大小等信息。在收包處理線程中,對(duì)數(shù)據(jù)包的拆包等操作,同樣的不需要拷貝到新的緩沖區(qū)中,利用包描述符提供的包地址,大小等信息進(jìn)行處理即可。
2.2 設(shè)置多級(jí)優(yōu)先級(jí)隊(duì)列
在網(wǎng)絡(luò)數(shù)據(jù)傳輸中,由于有些緊急數(shù)據(jù)希望盡快發(fā)送出去提交給目的主機(jī),而曰前的Windows系統(tǒng)網(wǎng)絡(luò)傳輸機(jī)制并沒(méi)有提供這樣的功能??梢酝ㄟ^(guò)采用多級(jí)優(yōu)先級(jí)隊(duì)列的方式來(lái)達(dá)到一定的實(shí)時(shí)效果,比如對(duì)于緊急數(shù)據(jù),可以設(shè)置最高優(yōu)先級(jí)值,而一般數(shù)據(jù)就可以設(shè)置最低優(yōu)先級(jí)值。在用戶(hù)應(yīng)用程序中,對(duì)發(fā)送函數(shù)進(jìn)行封裝,新的發(fā)送函數(shù)有個(gè)優(yōu)先級(jí)參數(shù),通過(guò)指明優(yōu)先級(jí)參數(shù)值靈活處理數(shù)據(jù),當(dāng)提交給內(nèi)核時(shí),就按照優(yōu)先級(jí)值放到相對(duì)應(yīng)的優(yōu)先級(jí)隊(duì)列中。相應(yīng)的在內(nèi)核收包、發(fā)包緩沖區(qū)中,設(shè)置多級(jí)優(yōu)先級(jí)隊(duì)列,按照多級(jí)反饋隊(duì)列調(diào)度算法進(jìn)行處理,每個(gè)隊(duì)列的優(yōu)先級(jí)不同,并且每個(gè)隊(duì)列的被處理的時(shí)間不同,各個(gè)隊(duì)列的時(shí)間片是隨著優(yōu)先級(jí)的減少而增加的,優(yōu)先級(jí)越高的隊(duì)列中它的被線程處理的時(shí)間也就越短。比如緊急數(shù)據(jù)放到最高優(yōu)先級(jí)隊(duì)列中,遲緩的數(shù)據(jù)可以放到最低優(yōu)先級(jí)隊(duì)列中,在內(nèi)核的發(fā)包線程中,首先判斷最高優(yōu)先級(jí)隊(duì)列是否為空,不為空則優(yōu)先發(fā)送該隊(duì)列中的數(shù)據(jù)包,當(dāng)該隊(duì)列的時(shí)間用完,如果該隊(duì)列還有包沒(méi)有處理完,則把這些包鏈接到低一級(jí)的隊(duì)列尾部,然后判斷低一級(jí)優(yōu)先級(jí)隊(duì)列是否為空,重復(fù)以上的操作依次進(jìn)行下去,當(dāng)對(duì)最低優(yōu)先級(jí)隊(duì)列處理完后,再循環(huán)處理。如果線程在處理第i隊(duì)列的數(shù)據(jù)時(shí),這時(shí)候有新的用戶(hù)數(shù)據(jù)進(jìn)入到比i隊(duì)列優(yōu)先級(jí)高的j隊(duì)列中,則線程處理完該數(shù)據(jù)就立即去處理j隊(duì)列,這個(gè)可以用一個(gè)掩碼mask,每一位標(biāo)識(shí)一個(gè)隊(duì)列,當(dāng)隊(duì)列不為空,則該標(biāo)識(shí)位置為1,否則置為0。
2.3 封裝Socket層
創(chuàng)建Socket套接字,就是打開(kāi)設(shè)備對(duì)象(第一次是創(chuàng)建,之后就是打開(kāi)),而打開(kāi)設(shè)備對(duì)象就會(huì)創(chuàng)建一個(gè)內(nèi)核文件對(duì)象,這個(gè)內(nèi)核文件對(duì)象其實(shí)就可以映射創(chuàng)建的Socket套接字。對(duì)于打開(kāi)設(shè)備對(duì)象,就可以用CreateFile()函數(shù),并且把返回的句柄定義為Socekt句柄,之后的操作就可以直接用這個(gè)Socket句柄進(jìn)行操作,如send()函數(shù),可以用WriteFile()函數(shù)封裝實(shí)現(xiàn);Receive()函數(shù)可以用ReadFile()函數(shù)封裝實(shí)現(xiàn);bind()函數(shù)、setsockopt()函數(shù)、getsockopt()函數(shù)都可以通過(guò)DeviceIoControl()函數(shù)封裝實(shí)現(xiàn)。為了真正實(shí)現(xiàn)打開(kāi)設(shè)備等操作,需要在協(xié)議驅(qū)動(dòng)程序中塒各個(gè)用戶(hù)應(yīng)用程序下達(dá)的IRP請(qǐng)求進(jìn)行響應(yīng),用派遣函數(shù)就可以實(shí)現(xiàn)。在圖2中,用戶(hù)程序可以通過(guò)新封裝好的Socket層,使用原來(lái)同樣的Socket編程語(yǔ)句,這樣使用戶(hù)使用起來(lái)感覺(jué)沒(méi)有差別,對(duì)用戶(hù)是透明的。
2.4 協(xié)議驅(qū)動(dòng)
在應(yīng)用程序中,對(duì)同一個(gè)線程環(huán)境下的文件句柄的讀,寫(xiě)等,映射到內(nèi)核中的IRP I/O堆棧的內(nèi)核文件對(duì)象File()bject是同一個(gè)File()bject,這樣可以用內(nèi)核文件對(duì)象作為紐帶作用。在協(xié)議驅(qū)動(dòng)的設(shè)備擴(kuò)展NDISPROT_OPEN_CONTEXT結(jié)構(gòu)體內(nèi),建立一個(gè)File Port鏈表,如圖3所示。鏈表的每個(gè)節(jié)點(diǎn)包含有內(nèi)核文件對(duì)象、接收數(shù)據(jù)緩沖區(qū)、發(fā)送數(shù)據(jù)緩沖區(qū)、端口號(hào)、接收數(shù)據(jù)緩沖區(qū)大小、發(fā)送數(shù)據(jù)緩沖區(qū)大小等兒部分。內(nèi)核文件對(duì)象用來(lái)標(biāo)識(shí)是哪一個(gè)用戶(hù)Socket句柄;接收、發(fā)送數(shù)據(jù)緩沖區(qū)用來(lái)存放Socket的接收、發(fā)送的數(shù)據(jù);端口號(hào)的作用是讓網(wǎng)絡(luò)數(shù)據(jù)包可以知道提交到哪個(gè)內(nèi)核文件對(duì)象下的接收緩沖區(qū);接收、發(fā)送數(shù)據(jù)緩沖區(qū)大小指明接收、發(fā)送緩沖區(qū)最大的長(zhǎng)度。如果緩沖區(qū)隊(duì)列滿(mǎn),而這時(shí)候又有數(shù)據(jù)過(guò)來(lái),則該數(shù)據(jù)應(yīng)被丟棄。在協(xié)議驅(qū)動(dòng)程序里面,利用這個(gè)FilePort鏈表,可以實(shí)現(xiàn)收發(fā)數(shù)據(jù),設(shè)置接收、發(fā)送緩沖區(qū)的大小等操作。
需要注意的是在NDISPROT_OPEN_CONTEXT結(jié)構(gòu)體內(nèi),需創(chuàng)建一個(gè)NPROT_LOCK類(lèi)型的鎖,用來(lái)對(duì)FilePort鏈表進(jìn)行互斥訪問(wèn)。
2.4.1 端口號(hào)的綁定
在協(xié)議驅(qū)動(dòng)設(shè)備擴(kuò)展中需要建立一張表,里面存放已默認(rèn)分配的端口號(hào)以及用戶(hù)綁定的端口號(hào),端口號(hào)是從小到大按序排列,表的作用是當(dāng)用戶(hù)應(yīng)用程序綁定端口號(hào)操作時(shí),首先會(huì)通過(guò)二叉查找法查找這張表,看該端口號(hào)是否存放在該表中,如果找到,則要返回給應(yīng)用程序綁定失敗,如果沒(méi)有找到,則把該端口號(hào)插入到適當(dāng)位置,并返回給應(yīng)用程序綁定成功。用戶(hù)應(yīng)用程序通過(guò)調(diào)用bind()函數(shù)實(shí)現(xiàn)綁定Socket套接字,其含義就是用端口號(hào)來(lái)惟一標(biāo)識(shí)用戶(hù)線程下的Socket,讓網(wǎng)絡(luò)數(shù)據(jù)包提交給正確的Socket,在bind函數(shù)里面可以通過(guò)封裝DeviceIo Control函數(shù)調(diào)用來(lái)實(shí)現(xiàn)。
2.4.2 發(fā)送數(shù)據(jù)過(guò)程
用戶(hù)應(yīng)用程序發(fā)送的IRP寫(xiě)請(qǐng)求(WriteFile()函數(shù)),傳遞到協(xié)議驅(qū)動(dòng)程序后,調(diào)用派遣函數(shù)NdisProtWrite,通過(guò)IRP I/O堆棧里面的內(nèi)核文件對(duì)象循環(huán)遍歷FilePort鏈表找到對(duì)應(yīng)的節(jié)點(diǎn),然后把用戶(hù)應(yīng)用程序的數(shù)據(jù)通過(guò)緩沖區(qū)讀寫(xiě)設(shè)備的方式拷貝到NDISPROT_OPEN_CONTEXT結(jié)構(gòu)的相應(yīng)的Priority SendQueue優(yōu)先級(jí)隊(duì)列中。如圖3所示,發(fā)包線程的工作主要有,從Priority SendQueue優(yōu)先級(jí)隊(duì)列中提取數(shù)據(jù),如何提取按照多級(jí)反饋隊(duì)列調(diào)度算法處理,經(jīng)過(guò)簡(jiǎn)化的TCP/IP協(xié)議棧,然后再調(diào)用NdisSendPackets函數(shù)發(fā)送給網(wǎng)卡驅(qū)動(dòng)程序。在TCP/IP協(xié)議棧中,把該數(shù)據(jù)的優(yōu)先級(jí)值賦值給IP首部的服務(wù)類(lèi)型(TOS)字段中,使收包的時(shí)候根據(jù)此字段的優(yōu)先級(jí)值把包放進(jìn)相應(yīng)的收包優(yōu)先級(jí)隊(duì)列中。
2.4.3 接收數(shù)據(jù)過(guò)程
協(xié)議驅(qū)動(dòng)從網(wǎng)卡驅(qū)動(dòng)程序接收網(wǎng)絡(luò)數(shù)據(jù)包,這些數(shù)據(jù)包是打包封裝好的,首先存放在NDISPROT_OPEN_CONTEXT結(jié)構(gòu)的收包優(yōu)先級(jí)隊(duì)列Pri ority RecvQueue中,這樣可以接收到高速上傳過(guò)來(lái)的底層數(shù)據(jù)。如圖3所示,需要建立一個(gè)收包處理線程,它的主要工作是,從收包優(yōu)先級(jí)隊(duì)列提取數(shù)據(jù),具體算法根據(jù)上面的多級(jí)反饋隊(duì)列調(diào)度算法,然后經(jīng)由TCP/IP協(xié)議棧的處理,如果是UDP,TCP的數(shù)據(jù)包則通過(guò)包的目的端口號(hào),遍歷FilePort鏈表找到對(duì)應(yīng)的節(jié)點(diǎn),然后把剩下的凈數(shù)據(jù)提交給節(jié)點(diǎn)(目標(biāo)Socket)的收包緩沖區(qū)中。值得注意的是,因?yàn)镹DIS封裝數(shù)據(jù)用的是NDIS_PACKET結(jié)構(gòu),NDIS_PACKET結(jié)構(gòu)里面包含一個(gè)NDIS_BUFFER結(jié)構(gòu)的鏈表,在每個(gè)NDIS_BUFFER里面才真正指向數(shù)據(jù)的首地址,這里說(shuō)的提交,并沒(méi)有拷貝數(shù)據(jù),只是把凈數(shù)據(jù)的首地址再次鏈接到FilePort鏈表中。當(dāng)用戶(hù)應(yīng)用程序通過(guò)Receive()函數(shù)接收數(shù)據(jù)的時(shí)候,會(huì)調(diào)用ReadFile()函數(shù),發(fā)出讀IRP請(qǐng)求,IRP到達(dá)協(xié)議驅(qū)動(dòng)后,調(diào)用NdisProtRead()派遣函數(shù)處理,NdisProtRead()會(huì)通過(guò)IRP I/O堆棧里面的內(nèi)核文件對(duì)象,遍歷FilePort鏈表,找到相應(yīng)的節(jié)點(diǎn),再把節(jié)點(diǎn)接收緩沖區(qū)里面的數(shù)據(jù)拷貝到用戶(hù)緩沖區(qū)里面。
3 測(cè)試與分析
3.1 測(cè)試環(huán)境和方法
測(cè)試時(shí),使用2臺(tái)主機(jī)分別作為客戶(hù)機(jī)和服務(wù)器。硬件和操作系統(tǒng)都是相同的配置,操作系統(tǒng)是Microsoft Windows XP Professional Service Pack 3,Pentium(R)Dual-Core CPU,主頻2.70 GHZ,內(nèi)存2 GB,網(wǎng)卡Realtek RTL8102E/RTL8103E,交換機(jī)為朗訊Lucent Cajun P116T。測(cè)試的主要目的是分析簡(jiǎn)化后的網(wǎng)絡(luò)相對(duì)于原來(lái)系統(tǒng)而言,在通訊延遲方面有何改進(jìn)。測(cè)試的方法采用如下方案:在局域網(wǎng)內(nèi),采用UDP數(shù)據(jù)報(bào)進(jìn)行通信測(cè)試,從客戶(hù)機(jī)向服務(wù)器發(fā)送數(shù)據(jù),數(shù)據(jù)長(zhǎng)度為300 B,即ping-pong測(cè)試,客戶(hù)端取1 000次的往返時(shí)間作為測(cè)試參數(shù),對(duì)沒(méi)有簡(jiǎn)化TCP/IP協(xié)議棧之前的客戶(hù)端與簡(jiǎn)化之后的客戶(hù)端進(jìn)行相同的測(cè)試,記錄次數(shù)15次。
3.2 結(jié)果分析
從圖4中可以看出,經(jīng)過(guò)對(duì)協(xié)議棧簡(jiǎn)化后,傳輸時(shí)間明顯大大減少。經(jīng)計(jì)算,簡(jiǎn)化前平均耗時(shí)1.241 s,而簡(jiǎn)化后的平均耗時(shí)為0.072 s,減少了94.198%,簡(jiǎn)化前耗時(shí)的樣本標(biāo)準(zhǔn)差為0.038 2,簡(jiǎn)化后耗時(shí)的樣本標(biāo)準(zhǔn)差為0.004 9,顯然簡(jiǎn)化后的穩(wěn)定性要更好。測(cè)試結(jié)果表明,經(jīng)過(guò)簡(jiǎn)化后的這種設(shè)計(jì),耗時(shí)和穩(wěn)定性能都能到達(dá)很好的效果。
4 結(jié)語(yǔ)
本文討論了一種簡(jiǎn)化現(xiàn)有的Windows系統(tǒng)TCP/IP協(xié)議棧的一種方法,減少了驅(qū)動(dòng)結(jié)構(gòu)層次,使用戶(hù)應(yīng)用程序的數(shù)據(jù)能較快提交給協(xié)議驅(qū)動(dòng)程序,協(xié)議驅(qū)動(dòng)程序通過(guò)封裝Socket,并且設(shè)置多級(jí)優(yōu)先級(jí)隊(duì)列以及采用零拷貝技術(shù)。通過(guò)這些技術(shù)的使用,能使數(shù)據(jù)提交給網(wǎng)卡的系統(tǒng)開(kāi)銷(xiāo)減少,使數(shù)據(jù)發(fā)送時(shí)間延遲減少,能滿(mǎn)足一定的實(shí)時(shí)性能需求。