版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quá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)設計2</p><p> 4.TCP/IP協(xié)議的系統(tǒng)實現(xiàn)3</p><p&g
2、t;<b> 5. 結(jié)論11</b></p><p> 6. 詳細設計代碼12</p><p> Windows平臺下TCP/IP協(xié)議的設計與實現(xiàn)</p><p><b> 1. 引言</b></p><p> 本文背景基于一個TCP/IP協(xié)議改進項目,項目要求通過改進TCP/IP協(xié)議
3、擁塞控制算法 來提高無線網(wǎng)絡環(huán)境下的數(shù)據(jù)吞吐量。目前的TCP協(xié)議在無線網(wǎng)絡環(huán)境下無法區(qū)分出擁塞 丟包與誤碼丟包,根據(jù)這兩種不同的丟包原因需要對TCP的窗口進行不同的調(diào)整,因此需 要對現(xiàn)有的TCP/IP協(xié)議進行改進。針對這個需求提供的一個解決方案就是自己開發(fā)出一套 TCP/IP協(xié)議以替代系統(tǒng)TCP/IP協(xié)議,但是并不需要實現(xiàn)整個TCP/IP協(xié)議族,重點實現(xiàn)TCP 與IP協(xié)議即可。</p><p> 2. TCP/
4、IP協(xié)議概述</p><p> TCP/IP協(xié)議是Internet的技術基礎。Internet是一個廣域網(wǎng),是目前聯(lián)通世界上絕大多 數(shù)國家和地區(qū)的全球性信息系統(tǒng)。在Internet上,可以實現(xiàn)低成本、高速率、交互式的信息 查詢、信息發(fā)布、通訊聯(lián)絡以及協(xié)同作業(yè)等等現(xiàn)代化的工作、學習和生活。</p><p> TCP/IP協(xié)議族通常分為四個層次,應用層、傳輸層、網(wǎng)絡層和鏈路層。如圖1所示:
5、</p><p> 圖1 TCP/IP協(xié)議族四層結(jié)構(gòu)</p><p> 應用層向用戶提供一組常用的應用程序,比如電子郵件(SMTP)、文件傳輸訪問(FTP)、 遠程登錄(Telnet)等。</p><p> 傳輸層提供進程間端到端的通信。在TCP/IP協(xié)議族中,主要有兩種不同的傳輸協(xié)議: 傳輸控制協(xié)議(TCP)和用戶數(shù)據(jù)報協(xié)議(UDP)。TCP提供面向連接的、
6、可靠的(沒有數(shù)據(jù)重復 或丟失),全雙エ的數(shù)據(jù)流傳輸服務。而UDP則提供的是不可靠的面向無連接的數(shù)據(jù)傳輸服 務,其可靠性應由上層應用程序來支持。</p><p> 網(wǎng)絡層,主要負責數(shù)據(jù)包的分組及路由選擇。在TCP/IP協(xié)議族中,網(wǎng)絡層協(xié)議包括網(wǎng)際協(xié)議IP、互連網(wǎng)控制報文協(xié)議ICMP、地址轉(zhuǎn)換協(xié)議ARP和反向地址轉(zhuǎn)換協(xié)議RARR。</p><p> 鏈路層處于四層結(jié)構(gòu)的最低層,負責接收IP
7、數(shù)據(jù)報并通過網(wǎng)絡發(fā)送之,或從網(wǎng)絡上接 收物理幀,抽出IP數(shù)據(jù)報,交給IP層。通常包括網(wǎng)絡設備驅(qū)動程序及網(wǎng)絡接口卡等。</p><p> 3.TCP/IP協(xié)議的系統(tǒng)設計</p><p> 以Windows網(wǎng)絡體系結(jié)構(gòu)為基礎,參照Windows DDK中關于網(wǎng)絡協(xié)議驅(qū)動與傳輸驅(qū) 動接口 (TDI)的相關資料,以及考慮到與原有系統(tǒng)TCP/IP兼容,提出的設計方案如圖2所示。</p>
8、;<p> 圖2 TCP/IP協(xié)議設計框圖</p><p> 應用程序也就是根據(jù)協(xié)議開發(fā)的特定應用。這里是針對開發(fā)的TCP/IP協(xié)議編寫的一個 FTP小應用程序,用來測試開發(fā)的協(xié)議。應用程序通過Wm32 API[3]接口將其操作轉(zhuǎn)化成相 應的請求提交給TDI客戶。</p><p> 傳輸驅(qū)動程序接口(TDI)客戶是核心態(tài)的驅(qū)動程序。它的主要功能是完成上層應用 程序的請求
9、,或者根據(jù)該請求產(chǎn)生相應的TDI操作,并將該操作傳遞給下層的TDI傳輸器。 TDI客戶通過Win32 API接口與上層應用程序交互;通過TDI接口與下層TDI傳輸器進行交互。</p><p> TDI傳輸提供者(TDI Transport Provider)又稱為TDI傳輸器,NDIS協(xié)議驅(qū)動程序,以及協(xié)議驅(qū)動程序,是工作在核心態(tài)的協(xié)議驅(qū)動程序。其中TCP協(xié)議,IP協(xié)議,ARP協(xié)議 等都是在這個模塊中實現(xiàn)。它通
10、過TDI接口與上層的TDI客戶進行交互;通過NDIS接口 與下層微端口驅(qū)動進行交互。</p><p> NDIS下層微端口驅(qū)動程序是工作在核心態(tài)的驅(qū)動程序,它負責將TDI傳輸器接入至特 定的網(wǎng)絡適配器。它通過NDIS接口與上下層進行交互。</p><p> 4.TCP/IP協(xié)議的系統(tǒng)實現(xiàn)</p><p> 由圖2中可以看出,整個系統(tǒng)可分為四部分,應用程序、TD
11、I客戶、TDI傳輸器和下層 微端口驅(qū)動。事實上對于下層微端口驅(qū)動并不需要考慮,因為可以直接調(diào)用NDIS庫函數(shù)將 數(shù)據(jù)轉(zhuǎn)發(fā)到這層,處于這層上的驅(qū)動會自動將數(shù)據(jù)送出網(wǎng)絡適配器。因此真正需要開發(fā)的也 就是上面三個部分。應用程序是用來實現(xiàn)簡単文件傳輸?shù)?,因此考慮開發(fā)兩個小應用程序, 一個為服務器端,一個為客戶端,服務器端用來監(jiān)聽和處理來自客戶端的連接請求??蛻舳?主要是向服務器端請求連接和發(fā)送數(shù)據(jù)。TDI客戶負責將來自應用程序的請求進行相應的處
12、 理之后轉(zhuǎn)發(fā)給下層的TDI傳輸驅(qū)動。TDI傳輸驅(qū)動主要是實現(xiàn)TCP, IP等功能,并與下層的 NDIS接口進行交互。</p><p> 4.1 應用程序的實現(xiàn)</p><p> 客戶端可以通過本地的某個端口向?qū)Ψ桨l(fā)送數(shù)據(jù)。并顯示一些錯誤狀態(tài)。</p><p> 服務器端,可以指定在本地的某個端口監(jiān)聽連接請求,接收數(shù)據(jù),并顯示一些狀態(tài)。實現(xiàn):通過DeviceIO
13、Control 及相應ControlCode 來將命令傳輸?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ū)動)的符號鏈接,符號鏈接是下層</p><p> 驅(qū)動程序?qū)in32 子系統(tǒng)可見的引用符號,也就是代表了一個下層的
16、驅(qū)動。這個函數(shù)的功</p><p> 能是打開下層的TDI 客戶,并返回該設備句柄,以后對設備的所有操作都是通過該句柄來</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 是這里最重要的兩個參數(shù)。前者
19、是前面CreateFile 返回的句</p><p> 柄,代表設備對象,在這里即是下層的TDI 客戶,表明是對它進行操作;后者是I/O 控制碼,</p><p> 表明要在該設備上進行的操作類型,如發(fā)送數(shù)據(jù),這個控制碼可以是自定義的。</p><p> 在應用程序調(diào)用了DeviceIoControl 之后就將操作請求提交給了處于系統(tǒng)內(nèi)核中的TDI</p
20、><p><b> 客戶。</b></p><p> 4.2 TDI 客戶的實現(xiàn)</p><p> TDI 客戶將上層應用程序發(fā)過來的I/O 請求包 (IRP)進行處理,能在本層處理的則處理</p><p> 后直接返回,需要底層繼續(xù)完成的則先將當前的IRP 狀態(tài)設置為掛起,然后重新設置一個</p>&
21、lt;p> IRP 移交給下層驅(qū)動繼續(xù)處理。</p><p> 實現(xiàn): 主要是TirdcTcpIoControlDispatch 派遣例程的實現(xiàn)。這個派遣例程與</p><p> DeviceIoControl 函數(shù)相對應。其主要功能是根據(jù)應用程序的不同請求(攜帶在IRP 中的</p><p> IoControlCode)進行不同的處理。只是這里需要
22、額外考慮的是,需要在TDI 客戶的該例程</p><p> 中事先判斷下是對服務器端的TDI 客戶操作還是針對客戶端的TDI 客戶進行操作。</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ū)動程序中注冊的派遣例程都是pDeviceObject 和pIrp 這兩個參數(shù),前面代表了要操作</p><p> 的設備對象,后者代表I/O 請求類型。pDeviceObject 在這里具體的是只指服務器端的TDI</p><p> 客戶或客戶端的TDI 客戶?,F(xiàn)在以服務器的TDI 客戶為例,假設
25、要對其進行一個監(jiān)聽操作,</p><p> 則此時IRP 中所攜帶的IoControlCode 則是一個代表監(jiān)聽操作的控制碼。這個函數(shù)就是根據(jù)</p><p> 不同的控制碼來決定要進行的操作——直接完成IRP 或者是轉(zhuǎn)發(fā)請求到下層。</p><p> 對于我們的協(xié)議來說,很多情況下TDI 客戶是不能獨立完成一個IRP 請求的,需要轉(zhuǎn)</p>&
26、lt;p> 發(fā)到下層也就是它的TDI 傳輸器來繼續(xù)完成IRP 的。這個時候就會用到后面的兩個重要函</p><p> 數(shù)TdiBuildXXX,和IoCallDriver 了。</p><p> TdiBuildXXX 函數(shù)原型:</p><p> 根據(jù) IO 控制碼的不同,該函數(shù)的聲明也稍有區(qū)別。仍舊接著前面的事例,TDI 客戶不</p>
27、<p> 能夠獨自完成應用程序的監(jiān)聽請求,因此需要借助TdiBuildXXX 函數(shù)來生成相應的IRP,</p><p> 交給下層的TDI 傳輸器進行處理。這里的XXX 既代表不同的操作,對于監(jiān)聽來說,既是</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> 這個函數(shù)中最重要的三個參數(shù)是Irp、DevObj 和FileObj,第一個是預先分配好的一個IRP 結(jié)構(gòu)體指針;第二個是這個IRP 將要轉(zhuǎn)發(fā)到的設備對象,也就是TDI 傳輸器;第三個是TDI 傳輸器的文件對象指針,可以是代表傳輸?shù)刂返奈募ο?,可以是代表連接端點的文件</p><p> 對象,可以是
31、代表控制信道的文件對象,不同的文件對象上可以進行的操作也不一樣,比如TDI_LISTEN 操作只可以在代表連接端點的文件對象上進行。該函數(shù)主要是對新建的IRP 進</p><p> 行設置,關鍵是給這個IRP 設置了操作碼為TDI_LISTEN. 在創(chuàng)建了這個IRP 以后,TDI 客戶將這個IRP 請求轉(zhuǎn)發(fā)到它的TDI 傳輸器,這個過程是通過調(diào)用IoCallDriver 函數(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 請求轉(zhuǎn)發(fā)給指定的設備對象。在我們的程序中,既是將TDI 客戶中生成</p><p> 的IRP 發(fā)給下層的TDI 傳輸器,即我們的協(xié)議驅(qū)動進行處理。DeviceObject 為代表下層TDI</p><p> 傳輸器的設備對象,IRP 為要進行的操作,如前面事例中生
34、成的TDI_LISTEN 請求。</p><p> 在 TDI 客戶調(diào)用IoCallDriver 之后,IRP 請求就轉(zhuǎn)到了TDI 傳輸器,即我們的TCP/IP</p><p><b> 協(xié)議中處理了。</b></p><p> 4.3 TDI 傳輸器的實現(xiàn)</p><p> TDI 傳輸器也就是我們的協(xié)議驅(qū)動,
35、也就是TCP/IP 協(xié)議。簡單的說,這層的主要操作</p><p> 仍然是根據(jù)上層TDI 客戶提交過來的請求進行不同的處理。只不過這里又有特殊的含義,</p><p> 就是要完成TCP/IP 的相應功能,因此這一層是我們實現(xiàn)中最重要的部分。</p><p> 在這層中,TDI 傳輸器接收到上層TDI 客戶轉(zhuǎn)交過來的請求,系統(tǒng)根據(jù)用戶注冊的函</p&g
36、t;<p> 數(shù)入口找到處理請求的函數(shù)irdcTCPInternalDeviceControlDispatch。該函數(shù)則根據(jù)操作的對象和操作的類型進行不同的函數(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 代表了當
38、前的設備對象,也就是TDI 傳輸器。Irp 為IRP 請求指針,表明了要操作的文件對象和需要進行的操作。該函數(shù)首先根據(jù)不同的文件對象進行分類,然后對某一個文件對象可以進行的操作進行列表。當某一請求到來時,根據(jù)比較這些參數(shù)找到對應的操作。以下就按TCP/IP 協(xié)議對數(shù)據(jù)的處理流程詳細進行分析。依數(shù)據(jù)傳輸?shù)姆较虼笾驴梢苑殖砂l(fā)送和接收過程。</p><p> 4.3.1 發(fā)送過程</p><p&g
39、t; 上層應用程序發(fā)起一個發(fā)送請求。首先應用程序調(diào)用CreateFile 函數(shù)打開TDI 客戶,然后調(diào)用DeviceIoControl 將請求轉(zhuǎn)發(fā)到內(nèi)核的TDI 客戶,TDI 客戶進行相應的處理之后,調(diào)用TdibuildSend 設置一個 TDI_SEND 請求,然后再調(diào)用IoCallerDriver 將該請求轉(zhuǎn)發(fā)給TDI傳輸器,即TCP/IP 協(xié)議進行處理。為了描述主線,這里暫把先前TCP 建立連接的三次握手過程給省略了。發(fā)送過程如
40、圖3 所示。</p><p><b> 圖 3 發(fā)送框圖</b></p><p> 數(shù)據(jù)從TDI 客戶進入TDI 傳輸器后,經(jīng)過一系列的函數(shù)調(diào)用,生成適合在網(wǎng)絡上傳輸?shù)臄?shù)據(jù)包。這個過程包括對數(shù)據(jù)的封包,超時,創(chuàng)建重傳隊列,數(shù)據(jù)分片,路由設置等。發(fā)送數(shù)據(jù)時首先雙方應該建立連接前完成一個三次握手的過程,在連接建立以后雙方開始進行可靠的通信。圖4 所示為建立連接以后,發(fā)
41、送過程在TCP/IP 協(xié)議層中函數(shù)的調(diào)用流圖。TDI 傳輸器的派遣例程調(diào)用tcp_send 函數(shù)發(fā)送數(shù)據(jù),將數(shù)據(jù)轉(zhuǎn)入到TCP 層,完成TCP 層的包頭以及控制狀態(tài)的設置。在調(diào)用ip_queue_xmit 后,數(shù)據(jù)轉(zhuǎn)到IP 層進行處理,在這里完成IP 包格式的設置以及分片操作等。最后調(diào)用ether_output 函數(shù)設置好MAC 頭以后,一個完整的數(shù)據(jù)幀就行成了,然而為了符合NDIS 對數(shù)據(jù)包格式的封裝要求,這里需要對數(shù)據(jù)結(jié)構(gòu)進行調(diào)整。數(shù)
42、據(jù)在進入ether_output 函數(shù)前一直是以SK_BUFF的形式進行管理的,這個結(jié)構(gòu)體有四個指針,通過對這四個指針的上下移動來對數(shù)據(jù)進行操作。在進入ether_output 函數(shù)之后數(shù)據(jù)重新打包成適合NDIS 接口傳輸?shù)腜acket 形式。然后調(diào)用NDIS 函數(shù)NdisSe</p><p> 圖 4 發(fā)送過程TCP/IP 協(xié)議層函數(shù)流程圖</p><p> 4.3.2 接收過程&l
43、t;/p><p> 下層網(wǎng)卡接收到數(shù)據(jù)以后,將通知微端口驅(qū)動程序,微端口驅(qū)動程序再將數(shù)據(jù)指示給NDIS 協(xié)議驅(qū)動程序進行處理。在協(xié)議層中對數(shù)據(jù)進行一系列的處理之后再通知給TDI 客戶,TDI 客戶再將數(shù)據(jù)通知給上層應用程序。接收過程如圖5 所示。</p><p><b> 圖 5 接收框圖</b></p><p> 數(shù)據(jù)從微端口指示給NDIS
44、 協(xié)議驅(qū)動以后,首先將NDIS 層的數(shù)據(jù)包格式Packet 拆開組裝成SK_BUFF 的形式,設置好該結(jié)構(gòu)的各個成員。然后調(diào)整它的四個指針來獲取不同層的實際數(shù)據(jù)。首先分離出MAC 幀頭,判斷收到的包是否為IP 包,否則直接丟棄,是則繼續(xù)往上進入IP 層處理。然后分離出IP 頭,判斷當前包是否分片,是則等收齊所有分片以后重新組包往上傳遞,不是則直接上傳。最后分離出TCP 頭,通過分析TCP 頭中所攜帶的信息,以及當前TCP 所在的狀態(tài)來進
45、行相應的處理。如當前的TCP 狀態(tài)是尚未建立連接則調(diào)用tcp_rcv_state_process 函數(shù),該函數(shù)根據(jù)TCP 頭中標志位的置位情況來進行相應處理。如果已經(jīng)建立連接則調(diào)用tcp_rcv_established 函數(shù)進行數(shù)據(jù)的接收過程處理,將接收的數(shù)據(jù)加入隊列,當隊列滿了以后通過設置事件的信號態(tài)來指示上層的TDI 客戶有數(shù)據(jù)到達,然后TDI客戶以同樣的方式通知上層應用程序。接收過程TCP/IP 協(xié)議層中的函數(shù)調(diào)用過程如下圖6所示
46、。</p><p> 圖 6 接收過程TCP/IP 協(xié)議層函數(shù)流程圖</p><p><b> 5. 結(jié)論</b></p><p> 本文以RFC 文檔中關于TCP/IP 協(xié)議的標準規(guī)范為理論基礎,以Windows DDK 為開發(fā)工具,結(jié)合項目需求,設計開發(fā)了一套TCP/IP 協(xié)議。本套協(xié)議并未實現(xiàn)整個TCP/IP 協(xié)議族中的所有協(xié)議,只
47、是對TCP 和IP 部分進行了實現(xiàn)。在前面總體協(xié)議框架的設計基礎上,最終得到的產(chǎn)品有,F(xiàn)TP 測試應用程序,TDI 客戶及TCP/IP 協(xié)議(TDI 傳輸器)。下面是測試該TCP/IP 協(xié)議的部分截圖。圖7 為啟動加載TCP/IP 協(xié)議(irdcTCP)與TDI客戶(TdiTirdcTcp)的截圖。圖8 為協(xié)議接收數(shù)據(jù)的截圖。</p><p> 圖 7 啟動TCP/IP 協(xié)議與TDI 客戶截圖
48、圖8 接收數(shù)據(jù)截圖</p><p><b> 6. 詳細設計代碼</b></p><p> ?。?)映射網(wǎng)絡驅(qū)動器功能實現(xiàn);</p><p><b> 實現(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)絡驅(qū)動盤\'%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)絡驅(qū)動盤失敗!")
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("斷開網(wǎng)絡驅(qū)動器映射\'%s
55、\'成功!"),m_strLocal);</p><p> MessageBox(strText);</p><p><b> return;}</b></p><p> MessageBox(CString("斷開網(wǎng)絡驅(qū)動器映射失敗!"));</p><p><b&g
56、t; }</b></p><p> ?。?)單個Ip共享資源搜索實現(xiàn)。</p><p> ?。?)搜索所有計算機的共享資源實現(xiàn)。</p><p><b> 實現(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("硬盤驅(qū)動");}</p><p> else if(dwType==STYPE_PRINTQ)</p><p> {strType=CString("打印機序列");}</p><p> els
67、e if(dwType==STYPE_DEVICE)</p><p> {strType=CString("通信設備");}</p><p> else if(dwType==STYPE_IPC)</p><p> {strType=CString("進程間通信(IPC)");}</p><p>
68、; else if(dwType==STYPE_SPECIAL)</p><p> strType=CString("特殊共享");}</p><p> else if(dwType==STYPE_TEMPORARY)</p><p> {strType=CString("臨時共享")}</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("沒有共享信息!"));}</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、保存為文本實現(xiàn):</p><p> 將TEXT文檔保存在record。text文檔中,上圖保存后的文檔如下</p><p><b> 實現(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)絡名稱:")+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ù)共享資源的主機和類項進行排序?qū)崿F(xiàn):</p><p><b> 實現(xiàn)代碼如下:</b></p><p> struct DATA </p><p><b
91、> {</b></p><p> int subitem;// 點擊表頭的列數(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;//點擊的列項傳遞給col,
93、用來判斷點擊了第幾列</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是用來判斷是升序還是降序排列的函數(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) //這個for用來給表中的項添加上索引號</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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡綜合管理課程設計
- 網(wǎng)絡綜合管理課程設計
- tcpip網(wǎng)絡聊天課程設計
- Windows平臺下基于監(jiān)聽的網(wǎng)絡計費系統(tǒng)的設計與實現(xiàn).pdf
- Windows平臺下國稅網(wǎng)絡監(jiān)控與分析系統(tǒng)的設計與實現(xiàn).pdf
- Windows平臺下網(wǎng)絡流量分析系統(tǒng)的設計與實現(xiàn).pdf
- 綜合布線課程設計--宿舍樓網(wǎng)絡綜合布線
- 基于tcpip協(xié)議的網(wǎng)絡通信應用程序課程設計報告
- 網(wǎng)絡綜合課程設計--中小型企業(yè)網(wǎng)絡設計
- Windows平臺下網(wǎng)絡直播系統(tǒng)的實現(xiàn).pdf
- windows平臺下實現(xiàn)搭建openvpn虛擬專用網(wǎng)絡
- 計算機網(wǎng)絡課程設計--基于tcpip協(xié)議的網(wǎng)絡監(jiān)聽程序設計
- Windows平臺下基于Snort入侵檢測系統(tǒng)的設計與實現(xiàn).pdf
- windows平臺下實現(xiàn)搭建openvpn虛擬專用網(wǎng)絡
- 城市學院校園網(wǎng)絡綜合平臺的設計與實現(xiàn).pdf
- WINDOWS平臺下回歸測試應用工具的設計與實現(xiàn).pdf
- WINDOWS平臺下網(wǎng)絡會議客戶端的設計與開發(fā).pdf
- 《網(wǎng)絡綜合布線技術》課程整體教學設計
- 網(wǎng)絡綜合布線課程設計---三教圖形化信息管理系統(tǒng)實現(xiàn)
- 網(wǎng)絡綜合測量探針軟件系統(tǒng)設計與實現(xiàn).pdf
評論
0/150
提交評論