版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 目 錄</b></p><p><b> 1. 引言1</b></p><p> 2. TCP/IP協(xié)議概述1</p><p> 3.TCP/IP協(xié)議的系統(tǒng)設(shè)計(jì)2</p><p> 4.TCP/IP協(xié)議的系統(tǒng)實(shí)現(xiàn)3</p><p&g
2、t;<b> 5. 結(jié)論11</b></p><p> 6. 詳細(xì)設(shè)計(jì)代碼12</p><p> Windows平臺(tái)下TCP/IP協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)</p><p><b> 1. 引言</b></p><p> 本文背景基于一個(gè)TCP/IP協(xié)議改進(jìn)項(xiàng)目,項(xiàng)目要求通過(guò)改進(jìn)TCP/IP協(xié)議
3、擁塞控制算法 來(lái)提高無(wú)線網(wǎng)絡(luò)環(huán)境下的數(shù)據(jù)吞吐量。目前的TCP協(xié)議在無(wú)線網(wǎng)絡(luò)環(huán)境下無(wú)法區(qū)分出擁塞 丟包與誤碼丟包,根據(jù)這兩種不同的丟包原因需要對(duì)TCP的窗口進(jìn)行不同的調(diào)整,因此需 要對(duì)現(xiàn)有的TCP/IP協(xié)議進(jìn)行改進(jìn)。針對(duì)這個(gè)需求提供的一個(gè)解決方案就是自己開(kāi)發(fā)出一套 TCP/IP協(xié)議以替代系統(tǒng)TCP/IP協(xié)議,但是并不需要實(shí)現(xiàn)整個(gè)TCP/IP協(xié)議族,重點(diǎn)實(shí)現(xiàn)TCP 與IP協(xié)議即可。</p><p> 2. TCP/
4、IP協(xié)議概述</p><p> TCP/IP協(xié)議是Internet的技術(shù)基礎(chǔ)。Internet是一個(gè)廣域網(wǎng),是目前聯(lián)通世界上絕大多 數(shù)國(guó)家和地區(qū)的全球性信息系統(tǒng)。在Internet上,可以實(shí)現(xiàn)低成本、高速率、交互式的信息 查詢、信息發(fā)布、通訊聯(lián)絡(luò)以及協(xié)同作業(yè)等等現(xiàn)代化的工作、學(xué)習(xí)和生活。</p><p> TCP/IP協(xié)議族通常分為四個(gè)層次,應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和鏈路層。如圖1所示:
5、</p><p> 圖1 TCP/IP協(xié)議族四層結(jié)構(gòu)</p><p> 應(yīng)用層向用戶提供一組常用的應(yīng)用程序,比如電子郵件(SMTP)、文件傳輸訪問(wèn)(FTP)、 遠(yuǎn)程登錄(Telnet)等。</p><p> 傳輸層提供進(jìn)程間端到端的通信。在TCP/IP協(xié)議族中,主要有兩種不同的傳輸協(xié)議: 傳輸控制協(xié)議(TCP)和用戶數(shù)據(jù)報(bào)協(xié)議(UDP)。TCP提供面向連接的、
6、可靠的(沒(méi)有數(shù)據(jù)重復(fù) 或丟失),全雙エ的數(shù)據(jù)流傳輸服務(wù)。而UDP則提供的是不可靠的面向無(wú)連接的數(shù)據(jù)傳輸服 務(wù),其可靠性應(yīng)由上層應(yīng)用程序來(lái)支持。</p><p> 網(wǎng)絡(luò)層,主要負(fù)責(zé)數(shù)據(jù)包的分組及路由選擇。在TCP/IP協(xié)議族中,網(wǎng)絡(luò)層協(xié)議包括網(wǎng)際協(xié)議IP、互連網(wǎng)控制報(bào)文協(xié)議ICMP、地址轉(zhuǎn)換協(xié)議ARP和反向地址轉(zhuǎn)換協(xié)議RARR。</p><p> 鏈路層處于四層結(jié)構(gòu)的最低層,負(fù)責(zé)接收IP
7、數(shù)據(jù)報(bào)并通過(guò)網(wǎng)絡(luò)發(fā)送之,或從網(wǎng)絡(luò)上接 收物理幀,抽出IP數(shù)據(jù)報(bào),交給IP層。通常包括網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序及網(wǎng)絡(luò)接口卡等。</p><p> 3.TCP/IP協(xié)議的系統(tǒng)設(shè)計(jì)</p><p> 以Windows網(wǎng)絡(luò)體系結(jié)構(gòu)為基礎(chǔ),參照Windows DDK中關(guān)于網(wǎng)絡(luò)協(xié)議驅(qū)動(dòng)與傳輸驅(qū) 動(dòng)接口 (TDI)的相關(guān)資料,以及考慮到與原有系統(tǒng)TCP/IP兼容,提出的設(shè)計(jì)方案如圖2所示。</p>
8、;<p> 圖2 TCP/IP協(xié)議設(shè)計(jì)框圖</p><p> 應(yīng)用程序也就是根據(jù)協(xié)議開(kāi)發(fā)的特定應(yīng)用。這里是針對(duì)開(kāi)發(fā)的TCP/IP協(xié)議編寫(xiě)的一個(gè) FTP小應(yīng)用程序,用來(lái)測(cè)試開(kāi)發(fā)的協(xié)議。應(yīng)用程序通過(guò)Wm32 API[3]接口將其操作轉(zhuǎn)化成相 應(yīng)的請(qǐng)求提交給TDI客戶。</p><p> 傳輸驅(qū)動(dòng)程序接口(TDI)客戶是核心態(tài)的驅(qū)動(dòng)程序。它的主要功能是完成上層應(yīng)用 程序的請(qǐng)求
9、,或者根據(jù)該請(qǐng)求產(chǎn)生相應(yīng)的TDI操作,并將該操作傳遞給下層的TDI傳輸器。 TDI客戶通過(guò)Win32 API接口與上層應(yīng)用程序交互;通過(guò)TDI接口與下層TDI傳輸器進(jìn)行交互。</p><p> TDI傳輸提供者(TDI Transport Provider)又稱為T(mén)DI傳輸器,NDIS協(xié)議驅(qū)動(dòng)程序,以及協(xié)議驅(qū)動(dòng)程序,是工作在核心態(tài)的協(xié)議驅(qū)動(dòng)程序。其中TCP協(xié)議,IP協(xié)議,ARP協(xié)議 等都是在這個(gè)模塊中實(shí)現(xiàn)。它通
10、過(guò)TDI接口與上層的TDI客戶進(jìn)行交互;通過(guò)NDIS接口 與下層微端口驅(qū)動(dòng)進(jìn)行交互。</p><p> NDIS下層微端口驅(qū)動(dòng)程序是工作在核心態(tài)的驅(qū)動(dòng)程序,它負(fù)責(zé)將TDI傳輸器接入至特 定的網(wǎng)絡(luò)適配器。它通過(guò)NDIS接口與上下層進(jìn)行交互。</p><p> 4.TCP/IP協(xié)議的系統(tǒng)實(shí)現(xiàn)</p><p> 由圖2中可以看出,整個(gè)系統(tǒng)可分為四部分,應(yīng)用程序、TD
11、I客戶、TDI傳輸器和下層 微端口驅(qū)動(dòng)。事實(shí)上對(duì)于下層微端口驅(qū)動(dòng)并不需要考慮,因?yàn)榭梢灾苯诱{(diào)用NDIS庫(kù)函數(shù)將 數(shù)據(jù)轉(zhuǎn)發(fā)到這層,處于這層上的驅(qū)動(dòng)會(huì)自動(dòng)將數(shù)據(jù)送出網(wǎng)絡(luò)適配器。因此真正需要開(kāi)發(fā)的也 就是上面三個(gè)部分。應(yīng)用程序是用來(lái)實(shí)現(xiàn)簡(jiǎn)単文件傳輸?shù)?,因此考慮開(kāi)發(fā)兩個(gè)小應(yīng)用程序, 一個(gè)為服務(wù)器端,一個(gè)為客戶端,服務(wù)器端用來(lái)監(jiān)聽(tīng)和處理來(lái)自客戶端的連接請(qǐng)求??蛻舳?主要是向服務(wù)器端請(qǐng)求連接和發(fā)送數(shù)據(jù)。TDI客戶負(fù)責(zé)將來(lái)自應(yīng)用程序的請(qǐng)求進(jìn)行相應(yīng)的處
12、 理之后轉(zhuǎn)發(fā)給下層的TDI傳輸驅(qū)動(dòng)。TDI傳輸驅(qū)動(dòng)主要是實(shí)現(xiàn)TCP, IP等功能,并與下層的 NDIS接口進(jìn)行交互。</p><p> 4.1 應(yīng)用程序的實(shí)現(xiàn)</p><p> 客戶端可以通過(guò)本地的某個(gè)端口向?qū)Ψ桨l(fā)送數(shù)據(jù)。并顯示一些錯(cuò)誤狀態(tài)。</p><p> 服務(wù)器端,可以指定在本地的某個(gè)端口監(jiān)聽(tīng)連接請(qǐng)求,接收數(shù)據(jù),并顯示一些狀態(tài)。實(shí)現(xiàn):通過(guò)DeviceIO
13、Control 及相應(yīng)ControlCode 來(lái)將命令傳輸?shù)较聦拥腡DI 客戶。主要接口函數(shù):CreateFile 和DeviceIoControl</p><p> CreateFile 函數(shù)原型:</p><p> HANDLE CreateFile(</p><p> LPCTSTR lpFileName,</p><p> D
14、WORD dwDesiredAccess,</p><p> DWORD dwShareMode,</p><p> LPSECURITY_ATTRIBUTES lpSecurityAttributes,</p><p> DWORD dwCreationDisposition,</p><p> DWORD dwFlagsAndAt
15、tributes,</p><p> HANDLE hTemplateFile</p><p><b> );</b></p><p> lpFileName 在這里就是指向要操作的TDI 客戶(驅(qū)動(dòng))的符號(hào)鏈接,符號(hào)鏈接是下層</p><p> 驅(qū)動(dòng)程序?qū)in32 子系統(tǒng)可見(jiàn)的引用符號(hào),也就是代表了一個(gè)下層的
16、驅(qū)動(dòng)。這個(gè)函數(shù)的功</p><p> 能是打開(kāi)下層的TDI 客戶,并返回該設(shè)備句柄,以后對(duì)設(shè)備的所有操作都是通過(guò)該句柄來(lái)</p><p><b> 引用。</b></p><p> DeviceIoControl 函數(shù)原型:</p><p> BOOL DeviceIoControl(</p>&l
17、t;p> HANDLE hDevice,</p><p> DWORD dwIoControlCode,</p><p> LPVOID lpInBuffer,</p><p> DWORD nInBufferSize,</p><p> LPVOID lpOutBuffer,</p><p> DW
18、ORD nOutBufferSize,</p><p> LPDWORD lpBytesReturned,</p><p> LPOVERLAPPED lpOverlapped</p><p><b> );</b></p><p> hDevice 和dwIoControlCode 是這里最重要的兩個(gè)參數(shù)。前者
19、是前面CreateFile 返回的句</p><p> 柄,代表設(shè)備對(duì)象,在這里即是下層的TDI 客戶,表明是對(duì)它進(jìn)行操作;后者是I/O 控制碼,</p><p> 表明要在該設(shè)備上進(jìn)行的操作類型,如發(fā)送數(shù)據(jù),這個(gè)控制碼可以是自定義的。</p><p> 在應(yīng)用程序調(diào)用了DeviceIoControl 之后就將操作請(qǐng)求提交給了處于系統(tǒng)內(nèi)核中的TDI</p
20、><p><b> 客戶。</b></p><p> 4.2 TDI 客戶的實(shí)現(xiàn)</p><p> TDI 客戶將上層應(yīng)用程序發(fā)過(guò)來(lái)的I/O 請(qǐng)求包 (IRP)進(jìn)行處理,能在本層處理的則處理</p><p> 后直接返回,需要底層繼續(xù)完成的則先將當(dāng)前的IRP 狀態(tài)設(shè)置為掛起,然后重新設(shè)置一個(gè)</p>&
21、lt;p> IRP 移交給下層驅(qū)動(dòng)繼續(xù)處理。</p><p> 實(shí)現(xiàn): 主要是TirdcTcpIoControlDispatch 派遣例程的實(shí)現(xiàn)。這個(gè)派遣例程與</p><p> DeviceIoControl 函數(shù)相對(duì)應(yīng)。其主要功能是根據(jù)應(yīng)用程序的不同請(qǐng)求(攜帶在IRP 中的</p><p> IoControlCode)進(jìn)行不同的處理。只是這里需要
22、額外考慮的是,需要在TDI 客戶的該例程</p><p> 中事先判斷下是對(duì)服務(wù)器端的TDI 客戶操作還是針對(duì)客戶端的TDI 客戶進(jìn)行操作。</p><p> 主要接口函數(shù):XXX_IOControlDispatch,</p><p> TdiBuildXXX 和IoCallDriver。</p><p> XXX_IOControl
23、Dispatch 函數(shù)原型:</p><p><b> NTSTATUS</b></p><p> XXX_DeviceIoControl(</p><p> IN PDEVICE_OBJECT pDeviceObject,</p><p> IN PIRP pIrp</p><p>&l
24、t;b> );</b></p><p> 驅(qū)動(dòng)程序中注冊(cè)的派遣例程都是pDeviceObject 和pIrp 這兩個(gè)參數(shù),前面代表了要操作</p><p> 的設(shè)備對(duì)象,后者代表I/O 請(qǐng)求類型。pDeviceObject 在這里具體的是只指服務(wù)器端的TDI</p><p> 客戶或客戶端的TDI 客戶?,F(xiàn)在以服務(wù)器的TDI 客戶為例,假設(shè)
25、要對(duì)其進(jìn)行一個(gè)監(jiān)聽(tīng)操作,</p><p> 則此時(shí)IRP 中所攜帶的IoControlCode 則是一個(gè)代表監(jiān)聽(tīng)操作的控制碼。這個(gè)函數(shù)就是根據(jù)</p><p> 不同的控制碼來(lái)決定要進(jìn)行的操作——直接完成IRP 或者是轉(zhuǎn)發(fā)請(qǐng)求到下層。</p><p> 對(duì)于我們的協(xié)議來(lái)說(shuō),很多情況下TDI 客戶是不能獨(dú)立完成一個(gè)IRP 請(qǐng)求的,需要轉(zhuǎn)</p>&
26、lt;p> 發(fā)到下層也就是它的TDI 傳輸器來(lái)繼續(xù)完成IRP 的。這個(gè)時(shí)候就會(huì)用到后面的兩個(gè)重要函</p><p> 數(shù)TdiBuildXXX,和IoCallDriver 了。</p><p> TdiBuildXXX 函數(shù)原型:</p><p> 根據(jù) IO 控制碼的不同,該函數(shù)的聲明也稍有區(qū)別。仍舊接著前面的事例,TDI 客戶不</p>
27、<p> 能夠獨(dú)自完成應(yīng)用程序的監(jiān)聽(tīng)請(qǐng)求,因此需要借助TdiBuildXXX 函數(shù)來(lái)生成相應(yīng)的IRP,</p><p> 交給下層的TDI 傳輸器進(jìn)行處理。這里的XXX 既代表不同的操作,對(duì)于監(jiān)聽(tīng)來(lái)說(shuō),既是</p><p> TdiBuildListen。其函數(shù)原型如下:</p><p><b> VOID</b><
28、/p><p> TdiBuildListen(</p><p><b> PIRP Irp,</b></p><p> PDEVICE_OBJECT DevObj,</p><p> PFILE_OBJECT FileObj,</p><p> PVOID CompRoutine,</
29、p><p> PVOID Contxt,</p><p> ULONG Flags,</p><p> PTDI_CONNECTION_INFORMATION RequestConnectionInfo,</p><p> PTDI_CONNECTION_INFORMATION ReturnConnectionInfo</p>
30、<p><b> );</b></p><p> 這個(gè)函數(shù)中最重要的三個(gè)參數(shù)是Irp、DevObj 和FileObj,第一個(gè)是預(yù)先分配好的一個(gè)IRP 結(jié)構(gòu)體指針;第二個(gè)是這個(gè)IRP 將要轉(zhuǎn)發(fā)到的設(shè)備對(duì)象,也就是TDI 傳輸器;第三個(gè)是TDI 傳輸器的文件對(duì)象指針,可以是代表傳輸?shù)刂返奈募?duì)象,可以是代表連接端點(diǎn)的文件</p><p> 對(duì)象,可以是
31、代表控制信道的文件對(duì)象,不同的文件對(duì)象上可以進(jìn)行的操作也不一樣,比如TDI_LISTEN 操作只可以在代表連接端點(diǎn)的文件對(duì)象上進(jìn)行。該函數(shù)主要是對(duì)新建的IRP 進(jìn)</p><p> 行設(shè)置,關(guān)鍵是給這個(gè)IRP 設(shè)置了操作碼為T(mén)DI_LISTEN. 在創(chuàng)建了這個(gè)IRP 以后,TDI 客戶將這個(gè)IRP 請(qǐng)求轉(zhuǎn)發(fā)到它的TDI 傳輸器,這個(gè)過(guò)程是通過(guò)調(diào)用IoCallDriver 函數(shù)來(lái)實(shí)現(xiàn)的。</p>&
32、lt;p> IoCallDriver 函數(shù)原型:</p><p><b> NTSTATUS</b></p><p> IoCallDriver(</p><p> IN PDEVICE_OBJECT DeviceObject,</p><p> IN OUT PIRP Irp</p>&l
33、t;p><b> );</b></p><p> 該函數(shù)將IRP 請(qǐng)求轉(zhuǎn)發(fā)給指定的設(shè)備對(duì)象。在我們的程序中,既是將TDI 客戶中生成</p><p> 的IRP 發(fā)給下層的TDI 傳輸器,即我們的協(xié)議驅(qū)動(dòng)進(jìn)行處理。DeviceObject 為代表下層TDI</p><p> 傳輸器的設(shè)備對(duì)象,IRP 為要進(jìn)行的操作,如前面事例中生
34、成的TDI_LISTEN 請(qǐng)求。</p><p> 在 TDI 客戶調(diào)用IoCallDriver 之后,IRP 請(qǐng)求就轉(zhuǎn)到了TDI 傳輸器,即我們的TCP/IP</p><p><b> 協(xié)議中處理了。</b></p><p> 4.3 TDI 傳輸器的實(shí)現(xiàn)</p><p> TDI 傳輸器也就是我們的協(xié)議驅(qū)動(dòng),
35、也就是TCP/IP 協(xié)議。簡(jiǎn)單的說(shuō),這層的主要操作</p><p> 仍然是根據(jù)上層TDI 客戶提交過(guò)來(lái)的請(qǐng)求進(jìn)行不同的處理。只不過(guò)這里又有特殊的含義,</p><p> 就是要完成TCP/IP 的相應(yīng)功能,因此這一層是我們實(shí)現(xiàn)中最重要的部分。</p><p> 在這層中,TDI 傳輸器接收到上層TDI 客戶轉(zhuǎn)交過(guò)來(lái)的請(qǐng)求,系統(tǒng)根據(jù)用戶注冊(cè)的函</p&g
36、t;<p> 數(shù)入口找到處理請(qǐng)求的函數(shù)irdcTCPInternalDeviceControlDispatch。該函數(shù)則根據(jù)操作的對(duì)象和操作的類型進(jìn)行不同的函數(shù)調(diào)用。</p><p> irdcTCPInternalDeviceControlDispatch 的函數(shù)原型:</p><p><b> NTSTATUS</b></p>&
37、lt;p> irdcTCPInternalDeviceControlDispatch(</p><p> IN PDEVICE_OBJECT DeviceObject,</p><p> IN PIRP Irp</p><p><b> )</b></p><p> 參數(shù)DeviceObject 代表了當(dāng)
38、前的設(shè)備對(duì)象,也就是TDI 傳輸器。Irp 為IRP 請(qǐng)求指針,表明了要操作的文件對(duì)象和需要進(jìn)行的操作。該函數(shù)首先根據(jù)不同的文件對(duì)象進(jìn)行分類,然后對(duì)某一個(gè)文件對(duì)象可以進(jìn)行的操作進(jìn)行列表。當(dāng)某一請(qǐng)求到來(lái)時(shí),根據(jù)比較這些參數(shù)找到對(duì)應(yīng)的操作。以下就按TCP/IP 協(xié)議對(duì)數(shù)據(jù)的處理流程詳細(xì)進(jìn)行分析。依數(shù)據(jù)傳輸?shù)姆较虼笾驴梢苑殖砂l(fā)送和接收過(guò)程。</p><p> 4.3.1 發(fā)送過(guò)程</p><p&g
39、t; 上層應(yīng)用程序發(fā)起一個(gè)發(fā)送請(qǐng)求。首先應(yīng)用程序調(diào)用CreateFile 函數(shù)打開(kāi)TDI 客戶,然后調(diào)用DeviceIoControl 將請(qǐng)求轉(zhuǎn)發(fā)到內(nèi)核的TDI 客戶,TDI 客戶進(jìn)行相應(yīng)的處理之后,調(diào)用TdibuildSend 設(shè)置一個(gè) TDI_SEND 請(qǐng)求,然后再調(diào)用IoCallerDriver 將該請(qǐng)求轉(zhuǎn)發(fā)給TDI傳輸器,即TCP/IP 協(xié)議進(jìn)行處理。為了描述主線,這里暫把先前TCP 建立連接的三次握手過(guò)程給省略了。發(fā)送過(guò)程如
40、圖3 所示。</p><p><b> 圖 3 發(fā)送框圖</b></p><p> 數(shù)據(jù)從TDI 客戶進(jìn)入TDI 傳輸器后,經(jīng)過(guò)一系列的函數(shù)調(diào)用,生成適合在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)包。這個(gè)過(guò)程包括對(duì)數(shù)據(jù)的封包,超時(shí),創(chuàng)建重傳隊(duì)列,數(shù)據(jù)分片,路由設(shè)置等。發(fā)送數(shù)據(jù)時(shí)首先雙方應(yīng)該建立連接前完成一個(gè)三次握手的過(guò)程,在連接建立以后雙方開(kāi)始進(jìn)行可靠的通信。圖4 所示為建立連接以后,發(fā)
41、送過(guò)程在TCP/IP 協(xié)議層中函數(shù)的調(diào)用流圖。TDI 傳輸器的派遣例程調(diào)用tcp_send 函數(shù)發(fā)送數(shù)據(jù),將數(shù)據(jù)轉(zhuǎn)入到TCP 層,完成TCP 層的包頭以及控制狀態(tài)的設(shè)置。在調(diào)用ip_queue_xmit 后,數(shù)據(jù)轉(zhuǎn)到IP 層進(jìn)行處理,在這里完成IP 包格式的設(shè)置以及分片操作等。最后調(diào)用ether_output 函數(shù)設(shè)置好MAC 頭以后,一個(gè)完整的數(shù)據(jù)幀就行成了,然而為了符合NDIS 對(duì)數(shù)據(jù)包格式的封裝要求,這里需要對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行調(diào)整。數(shù)
42、據(jù)在進(jìn)入ether_output 函數(shù)前一直是以SK_BUFF的形式進(jìn)行管理的,這個(gè)結(jié)構(gòu)體有四個(gè)指針,通過(guò)對(duì)這四個(gè)指針的上下移動(dòng)來(lái)對(duì)數(shù)據(jù)進(jìn)行操作。在進(jìn)入ether_output 函數(shù)之后數(shù)據(jù)重新打包成適合NDIS 接口傳輸?shù)腜acket 形式。然后調(diào)用NDIS 函數(shù)NdisSe</p><p> 圖 4 發(fā)送過(guò)程TCP/IP 協(xié)議層函數(shù)流程圖</p><p> 4.3.2 接收過(guò)程&l
43、t;/p><p> 下層網(wǎng)卡接收到數(shù)據(jù)以后,將通知微端口驅(qū)動(dòng)程序,微端口驅(qū)動(dòng)程序再將數(shù)據(jù)指示給NDIS 協(xié)議驅(qū)動(dòng)程序進(jìn)行處理。在協(xié)議層中對(duì)數(shù)據(jù)進(jìn)行一系列的處理之后再通知給TDI 客戶,TDI 客戶再將數(shù)據(jù)通知給上層應(yīng)用程序。接收過(guò)程如圖5 所示。</p><p><b> 圖 5 接收框圖</b></p><p> 數(shù)據(jù)從微端口指示給NDIS
44、 協(xié)議驅(qū)動(dòng)以后,首先將NDIS 層的數(shù)據(jù)包格式Packet 拆開(kāi)組裝成SK_BUFF 的形式,設(shè)置好該結(jié)構(gòu)的各個(gè)成員。然后調(diào)整它的四個(gè)指針來(lái)獲取不同層的實(shí)際數(shù)據(jù)。首先分離出MAC 幀頭,判斷收到的包是否為IP 包,否則直接丟棄,是則繼續(xù)往上進(jìn)入IP 層處理。然后分離出IP 頭,判斷當(dāng)前包是否分片,是則等收齊所有分片以后重新組包往上傳遞,不是則直接上傳。最后分離出TCP 頭,通過(guò)分析TCP 頭中所攜帶的信息,以及當(dāng)前TCP 所在的狀態(tài)來(lái)進(jìn)
45、行相應(yīng)的處理。如當(dāng)前的TCP 狀態(tài)是尚未建立連接則調(diào)用tcp_rcv_state_process 函數(shù),該函數(shù)根據(jù)TCP 頭中標(biāo)志位的置位情況來(lái)進(jìn)行相應(yīng)處理。如果已經(jīng)建立連接則調(diào)用tcp_rcv_established 函數(shù)進(jìn)行數(shù)據(jù)的接收過(guò)程處理,將接收的數(shù)據(jù)加入隊(duì)列,當(dāng)隊(duì)列滿了以后通過(guò)設(shè)置事件的信號(hào)態(tài)來(lái)指示上層的TDI 客戶有數(shù)據(jù)到達(dá),然后TDI客戶以同樣的方式通知上層應(yīng)用程序。接收過(guò)程TCP/IP 協(xié)議層中的函數(shù)調(diào)用過(guò)程如下圖6所示
46、。</p><p> 圖 6 接收過(guò)程TCP/IP 協(xié)議層函數(shù)流程圖</p><p><b> 5. 結(jié)論</b></p><p> 本文以RFC 文檔中關(guān)于TCP/IP 協(xié)議的標(biāo)準(zhǔn)規(guī)范為理論基礎(chǔ),以Windows DDK 為開(kāi)發(fā)工具,結(jié)合項(xiàng)目需求,設(shè)計(jì)開(kāi)發(fā)了一套TCP/IP 協(xié)議。本套協(xié)議并未實(shí)現(xiàn)整個(gè)TCP/IP 協(xié)議族中的所有協(xié)議,只
47、是對(duì)TCP 和IP 部分進(jìn)行了實(shí)現(xiàn)。在前面總體協(xié)議框架的設(shè)計(jì)基礎(chǔ)上,最終得到的產(chǎn)品有,F(xiàn)TP 測(cè)試應(yīng)用程序,TDI 客戶及TCP/IP 協(xié)議(TDI 傳輸器)。下面是測(cè)試該TCP/IP 協(xié)議的部分截圖。圖7 為啟動(dòng)加載TCP/IP 協(xié)議(irdcTCP)與TDI客戶(TdiTirdcTcp)的截圖。圖8 為協(xié)議接收數(shù)據(jù)的截圖。</p><p> 圖 7 啟動(dòng)TCP/IP 協(xié)議與TDI 客戶截圖
48、圖8 接收數(shù)據(jù)截圖</p><p><b> 6. 詳細(xì)設(shè)計(jì)代碼</b></p><p> (1)映射網(wǎng)絡(luò)驅(qū)動(dòng)器功能實(shí)現(xiàn);</p><p><b> 實(shí)現(xiàn)代碼如下:{</b></p><p> UpdateData(FALSE);</p><p> DWORD n
49、RetVal;</p><p> NETRESOURCE nr;</p><p> nr.dwType = RESOURCETYPE_ANY;</p><p> LPTSTR Local =(LPTSTR)(LPCTSTR)m_strLocal;</p><p> nr.lpLocalName=T2W(Local);<
50、/p><p> LPTSTR Tar =(LPTSTR)(LPCTSTR)m_strTar;</p><p> nr.lpRemoteName = T2W(Tar);</p><p> nr.lpProvider = NULL;</p><p> nRetVal = WNetAddConnection2(&nr, m_st
51、rPwd, m_strUser, FALSE);</p><p> if(nRetVal == NO_ERROR)</p><p> {CString strText;</p><p> strText.Format(CString("映射文件\'%s\'到網(wǎng)絡(luò)驅(qū)動(dòng)盤(pán)\'%s\'成功"), m_str
52、Tar, m_strLocal);</p><p> AfxMessageBox(strText);</p><p><b> return;</b></p><p><b> }</b></p><p> MessageBox(CString("映射網(wǎng)絡(luò)驅(qū)動(dòng)盤(pán)失敗!")
53、);}</p><p> void CMapDlg::OnBnClickedButtonDismap()</p><p><b> {</b></p><p> DWORD nRetVal;</p><p> UpdateData(TRUE);</p><p> nRetVal = WN
54、etCancelConnection2(m_strLocal, CONNECT_UPDATE_PROFILE, FALSE);</p><p> if(nRetVal == NO_ERROR)</p><p> {CString strText;</p><p> strText.Format(CString("斷開(kāi)網(wǎng)絡(luò)驅(qū)動(dòng)器映射\'%s
55、\'成功!"),m_strLocal);</p><p> MessageBox(strText);</p><p><b> return;}</b></p><p> MessageBox(CString("斷開(kāi)網(wǎng)絡(luò)驅(qū)動(dòng)器映射失敗!"));</p><p><b&g
56、t; }</b></p><p> (2)單個(gè)Ip共享資源搜索實(shí)現(xiàn)。</p><p> ?。?)搜索所有計(jì)算機(jī)的共享資源實(shí)現(xiàn)。</p><p><b> 實(shí)現(xiàn)代碼如下:</b></p><p> void Ctmp1Dlg::OnBnClickedOk()</p><p>
57、{m_ListCtrlres.DeleteAllItems();</p><p> if(m_Operate==0)</p><p> {BYTE bIP[4];</p><p> m_IPtar.GetAddress(bIP[0],bIP[1],bIP[2],bIP[3]);</p><p> CString tarAdd;t
58、arAdd.Format(CString("%d.%d.%d.%d"),bIP[0],bIP[1],bIP[2],bIP[3]);Search(tarAdd);</p><p> }else if(m_Operate==1)</p><p> {SearchAll();</p><p><b> }}</b>
59、</p><p> TCHAR* Ctmp1Dlg::CString2TCHAR(CString& str)</p><p> {int iLen = str.GetLength(); </p><p> TCHAR* szRs = new TCHAR[iLen]; </p><p> lstrcpy(szRs, str.G
60、etBuffer(iLen)); </p><p> str.ReleaseBuffer(); </p><p> return szRs; </p><p> }void Ctmp1Dlg::OnBnClickedRadioAll()</p><p> {GetDlgItem(IDC_IPADDRESS_TAR)->Enab
61、leWindow(0);</p><p> m_Operate=1;}</p><p> void Ctmp1Dlg::OnBnClickedRadioPer()</p><p> {GetDlgItem(IDC_IPADDRESS_TAR)->EnableWindow(1);</p><p> m_Operate=0;}&l
62、t;/p><p> int Ctmp1Dlg::Search(CString tarIP)</p><p> {TCHAR *tmp=CString2TCHAR(tarIP);</p><p> PSHARE_INFO_1 BufPtr,p;</p><p> NET_API_STATUS res;</p><p&g
63、t; LPTSTR lpszServer = NULL;</p><p> DWORD er=0,tr=0,resume=0, i;</p><p> lpszServer = tmp;</p><p> do // begin do{</p><p> res = NetShareEnum (lpszServer, 1,
64、(LPBYTE *) &BufPtr, -1, &er, &tr, &resume);</p><p> if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA){p=BufPtr;</p><p> for(i=0;i<er;i++)</p><p> {CS
65、tring strNetName=p->shi1_netname;</p><p> CString strRemark=p->shi1_remark;</p><p> DWORD dwType=p->shi1_type;</p><p> CString strType;</p><p> if(dwTy
66、pe==STYPE_DISKTREE)</p><p> {strType=CString("硬盤(pán)驅(qū)動(dòng)");}</p><p> else if(dwType==STYPE_PRINTQ)</p><p> {strType=CString("打印機(jī)序列");}</p><p> els
67、e if(dwType==STYPE_DEVICE)</p><p> {strType=CString("通信設(shè)備");}</p><p> else if(dwType==STYPE_IPC)</p><p> {strType=CString("進(jìn)程間通信(IPC)");}</p><p>
68、; else if(dwType==STYPE_SPECIAL)</p><p> strType=CString("特殊共享");}</p><p> else if(dwType==STYPE_TEMPORARY)</p><p> {strType=CString("臨時(shí)共享")}</p>
69、<p> else{strType.Format(CString("%d"),dwType);</p><p> }int nCount=m_ListCtrlres.GetItemCount();</p><p> m_ListCtrlres.InsertItem(nCount,tarIP,0);</p><p> m_
70、ListCtrlres.SetItemText(nCount,1,strNetName);</p><p> m_ListCtrlres.SetItemText(nCount,2,strRemark);</p><p> m_ListCtrlres.SetItemText(nCount,3,strType); </p><p> p++;}N
71、etApiBufferFree(BufPtr);}</p><p> else if(res!=ERROR_SUCCESS&&res!=ERROR_MORE_DATA&&m_Operate==0){MessageBox(CString("沒(méi)有共享信息!"));}</p><p> }while (res==ERROR_
72、MORE_DATA); // end do</p><p><b> return 0;</b></p><p> void Ctmp1Dlg::SearchAll(void)</p><p> {LPSERVER_INFO_101 pBuf = NULL;</p><p> LPSERVER_INFO_101
73、 pTmpBuf;</p><p> DWORD dwLevel = 101;</p><p> DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;</p><p> DWORD dwEntriesRead = 0;</p><p> DWORD dwTotalEntries = 0;</p&g
74、t;<p> DWORD dwServerType = SV_TYPE_SERVER; // all servers</p><p> DWORD dwResumeHandle = 0;</p><p> NET_API_STATUS nStatus;</p><p> LPTSTR pszServerName = NULL;&l
75、t;/p><p> LPTSTR pszDomainName = NULL;</p><p><b> DWORD i;</b></p><p> WSADATA wsaData;</p><p> WSAStartup(MAKEWORD(2,0), &wsaData);</p><p&
76、gt; nStatus = NetServerEnum(pszServerName,</p><p><b> dwLevel,</b></p><p> (LPBYTE *) & pBuf,</p><p> dwPrefMaxLen,</p><p> &dwEntriesRead,<
77、/p><p> &dwTotalEntries,</p><p> dwServerType, </p><p> pszDomainName, </p><p> &dwResumeHandle);</p><p> if ((nStatus == NERR_Success) || (nStat
78、us == ERROR_MORE_DATA)) {</p><p> if ((pTmpBuf = pBuf) != NULL) {</p><p> for (i = 0; i < dwEntriesRead; i++) {</p><p> CString HostName=pTmpBuf->sv101_name;</p><
79、;p> char szHostName[128]={'\0'};</p><p> int hostlength=HostName.GetLength();</p><p> for(int j=0;j<hostlength;j++)</p><p> {szHostName[j]=HostName[j];}</p&
80、gt;<p> hostent * ent = gethostbyname(szHostName);</p><p> if(ent==NULL){</p><p> pTmpBuf++;</p><p> continue;}</p><p> CString strHostIP;</p>
81、<p> in_addr* inHostIP=(in_addr *)ent->h_addr_list[0];strHostIP.Format(CString("%d.%d.%d.%d"),inHostIP->S_un.S_un_b.s_b1,inHostIP->S_un.S_un_b.s_b2,inHostIP->S_un.S_un_b.s_b3,inHostIP->
82、S_un.S_un_b.s_b4);Search(strHostIP);pTmpBuf++;</p><p> if (pBuf != NULL)NetApiBufferFree(pBuf);</p><p> WSACleanup();</p><p><b> }</b></p><p> ?。?)將搜索結(jié)果
83、保存為文本實(shí)現(xiàn):</p><p> 將TEXT文檔保存在record。text文檔中,上圖保存后的文檔如下</p><p><b> 實(shí)現(xiàn)代碼如下:</b></p><p> void Ctmp1Dlg::OnBnClickedButton2()</p><p><b> {</b><
84、/p><p> // TODO: 在此添加控件通知處理程序代碼</p><p> int nCount=m_ListCtrlres.GetItemCount();</p><p> CString strIpAdd;</p><p> CString strNetName;</p><p> CString st
85、rRemark;</p><p> CString strType;</p><p> CFile file;</p><p> file.Open(CString("Record.txt"),CFile::modeCreate|CFile::modeWrite);</p><p> for(int i=0;i&l
86、t;nCount;i++)</p><p><b> {</b></p><p> strIpAdd=m_ListCtrlres.GetItemText(i,0);</p><p> strNetName=m_ListCtrlres.GetItemText(i,1);</p><p> strRemark=
87、m_ListCtrlres.GetItemText(i,2);</p><p> strType=m_ListCtrlres.GetItemText(i,3);</p><p> CString str;</p><p> str=_T("IP地址:")+strIpAdd+_T(" 網(wǎng)絡(luò)名稱:")+strNet
88、Name+_T(" 注釋:")+strRemark+_T(" 類型:")+strType+_T("\r\n");</p><p> const unsigned char LeadBytes[] = {0xff,0xfe}; </p><p> file.Write(LeadBytes, sizeof(Lead
89、Bytes)); </p><p> file.Flush();</p><p> file.Write(str.GetBuffer(),str.GetLength()*sizeof(TCHAR));</p><p> file.Flush();</p><p><b> }</b></p>&l
90、t;p> file.Close();</p><p><b> }</b></p><p> (5)依據(jù)共享資源的主機(jī)和類項(xiàng)進(jìn)行排序?qū)崿F(xiàn):</p><p><b> 實(shí)現(xiàn)代碼如下:</b></p><p> struct DATA </p><p><b
91、> {</b></p><p> int subitem;// 點(diǎn)擊表頭的列數(shù)</p><p> CListCtrl* plist; //listctrl的指針</p><p><b> bool fav;</b></p><p><b> };</b></p>
92、;<p> int CALLBACK CompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)</p><p> {DATA* pListCtrl = (DATA*)lParamSort; </p><p> int col = pListCtrl->subitem;//點(diǎn)擊的列項(xiàng)傳遞給col,
93、用來(lái)判斷點(diǎn)擊了第幾列</p><p> CString strItem1 = (pListCtrl->plist)->GetItemText(lParam1, col); </p><p> CString strItem2 = (pListCtrl->plist)->GetItemText(lParam2, col); </p><p
94、> int n1=strItem2.Compare(strItem1);</p><p> if (pListCtrl->fav)//fav是用來(lái)判斷是升序還是降序排列的函數(shù)</p><p><b> {</b></p><p> return n1;</p><p><b> }
95、 </b></p><p><b> else</b></p><p><b> {</b></p><p><b> n1=-n1;</b></p><p> return n1;</p><p><b> }<
96、;/b></p><p><b> }</b></p><p> void Ctmp1Dlg::OnLvnColumnclickListRes(NMHDR *pNMHDR, LRESULT *pResult)</p><p><b> {</b></p><p> LPNMLISTVI
97、EW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);</p><p> // TODO: 在此添加控件通知處理程序代碼</p><p> for(int i = 0; i < m_ListCtrlres.GetItemCount(); ++i) //這個(gè)for用來(lái)給表中的項(xiàng)添加上索引號(hào)</p><p&
98、gt;<b> {</b></p><p> m_ListCtrlres.SetItemData(i,i); </p><p><b> }</b></p><p> DATA data;</p><p> data.subitem = pNMLV->iSubItem;//&
99、lt;/p><p> data.plist = &m_ListCtrlres;</p><p> if(fav%2==0)</p><p><b> {</b></p><p> data.fav=true;</p><p><b> }</b></p&g
100、t;<p> else data.fav=false;</p><p> fav++;//全局函數(shù)。</p><p> m_ListCtrlres.SortItems(CompareProc,(LPARAM)&data);</p><p> *pResult = 0;</p><p><b> }&l
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡(luò)綜合管理課程設(shè)計(jì)
- 網(wǎng)絡(luò)綜合管理課程設(shè)計(jì)
- tcpip網(wǎng)絡(luò)聊天課程設(shè)計(jì)
- Windows平臺(tái)下基于監(jiān)聽(tīng)的網(wǎng)絡(luò)計(jì)費(fèi)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- Windows平臺(tái)下國(guó)稅網(wǎng)絡(luò)監(jiān)控與分析系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- Windows平臺(tái)下網(wǎng)絡(luò)流量分析系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 綜合布線課程設(shè)計(jì)--宿舍樓網(wǎng)絡(luò)綜合布線
- 基于tcpip協(xié)議的網(wǎng)絡(luò)通信應(yīng)用程序課程設(shè)計(jì)報(bào)告
- 網(wǎng)絡(luò)綜合課程設(shè)計(jì)--中小型企業(yè)網(wǎng)絡(luò)設(shè)計(jì)
- Windows平臺(tái)下網(wǎng)絡(luò)直播系統(tǒng)的實(shí)現(xiàn).pdf
- windows平臺(tái)下實(shí)現(xiàn)搭建openvpn虛擬專用網(wǎng)絡(luò)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)--基于tcpip協(xié)議的網(wǎng)絡(luò)監(jiān)聽(tīng)程序設(shè)計(jì)
- Windows平臺(tái)下基于Snort入侵檢測(cè)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- windows平臺(tái)下實(shí)現(xiàn)搭建openvpn虛擬專用網(wǎng)絡(luò)
- 城市學(xué)院校園網(wǎng)絡(luò)綜合平臺(tái)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- WINDOWS平臺(tái)下回歸測(cè)試應(yīng)用工具的設(shè)計(jì)與實(shí)現(xiàn).pdf
- WINDOWS平臺(tái)下網(wǎng)絡(luò)會(huì)議客戶端的設(shè)計(jì)與開(kāi)發(fā).pdf
- 《網(wǎng)絡(luò)綜合布線技術(shù)》課程整體教學(xué)設(shè)計(jì)
- 網(wǎng)絡(luò)綜合布線課程設(shè)計(jì)---三教圖形化信息管理系統(tǒng)實(shí)現(xiàn)
- 網(wǎng)絡(luò)綜合測(cè)量探針軟件系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn).pdf
評(píng)論
0/150
提交評(píng)論