• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統計

            最新評論

            spi

            隨著WOSA模型的出現,在Ws2_32.dll和協議堆棧之間多了一層開放的接口,就是SPI。Winsock2 SPI和Winsock2 API在性質上是一樣的,只是他們的服務對象不同,API提供的接口工作在應用層的上層,為應用程序提供接口,在Winsock之上,而SPI提供的接口工作在應用層的最底層,為核心的網絡服務提供接口,在Winsock之下。如果按照OSI分層標準來劃分,SPI應該是工作在會話層,API工作在應用層。如果有人非要象我一開始這樣,非要分出個一二三四的話,這樣的理解或許能讓你得到一點滿足,當然這種理解不是完全正確的,但是至少在層次的先后上,這樣的理解應該是正確的。我們的工作逐漸進入了OSI的下層,要學習,就要多費一些口舌了。

            SPI的上沿是Ws2_32.dll,而它的下沿是協議堆棧和名字空間,當然分層服務可以多層疊放,擴展上下沿。這里講述向協議堆棧的服務。SPI包含兩種服務,一種是基礎服務,一種是分層服務。

            SPI實例實際上就是一個動態庫,開放了一個初始化函數:WSPStartup 或者 NSPStartup。其他函數的指針通過一個函數分配表在此初始化函數中指定給Ws2_32.dll。Ws2_32.dll在需要的時候將相應的服務/協議實現模塊裝載入內存,在不需要的時候卸載。

            一般來說,當一個應用程序調用 Winsock2 API 函數的時候,Winsock2 都會調用相應的 Winsock2 SPI 函數。如 WSPAccept, WSPConnect, etc. 下述特例不經過SPI:

            htonl,htons,ntohs,ntohl,inet_addr,inet_ntoa,gethostname,getXbyY,WSAAsnyGetXByY,wsacANCELaSYNCrEQUEST,WSAEnumProtocols,WSAIsBlocking,WSASetBlocking,WSAUnhookBlocking,WSAGetLastError,WSASetLastError,WSACreateEvent,WSACloseEvent,WSASetEvent,WSAResetEvent,WSAWaitForMultipleEvents.SPI的函數原型定義在ws2spi.h中,前綴都有WSP,NSP,WPU,WSC,有興趣可以瀏覽一下。相應的對應函數有30個。都會在WSPStartup的實現中得到這些函數指針。

            要注意的是:WSPStartup并不是在WSAStartup調用時被調用的,一旦要WSPStartup的時候也就是說明需要用到服務提供者了,那么Ws2_32什么時候加載服務提供者呢?應用程序創建了套接字的時候,Ws2_32就根據套接字的地址家族,類型,協議信息等加載相應的提供者,這時候,WSPStartup就會被調用,服務提供者就開始調度它的傳輸函數等等內容了。

            現在有個問題,既然我們知道Windows Sockets動態庫和協議堆棧之間沒有直接聯系了,那么,如果我的應用程序想要調用我的SPI實例的擴展函數的時候那該怎么辦呢?Ws2_32.dll不可能再擴展專門的函數調用,讓他按照規范再去調用協議堆棧提供者的擴展函數。其實,Ws2_32.dll提供了一個函數來解決這個額外的擴展問題,那就是WSAIoctl函數,通過命令碼 SIO_GET_EXTENSION_FUNCTION_POINTER,輸入緩沖區是擴展函數的標識符,輸出參數就是該函數的指針了。那么,應用程序就可以直接跳過Ws2_32.dll而直接調用擴展函數。

            在動手編寫SPI實例之前,我們需要了解一下基礎服務和分層服務的區別以及系統如何標志這兩種服務,然后講述如何在系統中安裝一個自己的SPI實例,來擴展你的網絡傳輸功能。以及如何卸載自己的SPI實例,來恢復系統原來默認的設置。最后再來講述如何編寫SPI的實例。

            基礎服務執行核心的網絡傳輸協議功能,而分層服務在基礎服務的基礎上執行自定義的通訊控制,所有的真正的數據交換是通過基礎服務提供者來實現的,分層服務提供者無需再去實現網絡協議的功能。簡單的網絡封包的截取和管理可以在此進行。

            需要提及套接字句柄。當調用下層SPI的時候,如果調用WSPSocket,WSPAccept,WSPJoinLeaf時,服務提供者必須返回一個套接字句柄,Winsock2允許在此句柄上直接調用 ReadFile/WriteFile來讀寫數據。這個句柄有兩種類型:IFS(可安裝文件系統句柄)和 Non IFS(不可安裝的文件系統句柄)。微軟的基礎服務提供者都是IFS句柄,但是分層服務提供者可以是IFS,也可以是Non IFS。但是如果分層提供者是IFS提供者,就必須將下一級IFS提供者的句柄上傳到上一級提供者或者WS2_32.dll,此時對套接字的ReadFile/WriteFile調用會跳過分層服務提供者的WSPSend/WSPRecv函數而直接通過基礎服務提供者的功能進行數據讀寫,而且分層服務提供者將不能處理一個完成端口的重疊I/0操作,這些操作也將繞過分層提供者,而直接通過基礎提供者完成數據的讀寫。所以,最好將分層服務提供者定義為Non IFS句柄的服務提供者,這樣就可以對網絡數據進行完整的監控。具體做法是在協議信息結構中將dwServiceFlags1標志的XP1_IFS_HANDLES標志去掉。這樣,你的分層提供這就是一個Non IFS分層服務提供者,Non IFS服務提供者使用WSPCreateSocketHandle上調函數建立套接字句柄,Winsock2會把ReadFile/WriteFile的調用重定向到WSPSend和WSPReceive上去,但這無疑會對系統性能產生負面影響。

            Windows系統為服務提供者維護了一個目錄,這些信息保存在注冊表中,要更改/安裝服務提供者,就必須對此目錄信息進行維護。系統提供了一些函數簡化對此信息的訪問,他們都是以WSC開頭。

            對于基礎服務提供者的安裝相當簡單,只要準備一個WSAPROTOCOL_INFOW結構,用來代表基礎服務提供者信息,正確填充合適的值,然后調用WSCInstallProvider函數就可以完成基礎服務提供者的安裝。但是這種方法只對新增加的基礎服務提供者來講是很方便的,但是我們往往要利用系統的基礎服務提供者來實現基本的協議,比如說TCP協議的實現,所以在這種情況下,方便的方法是不通過WSCInstallProvider函數,而是我們自己修改目錄條目信息,對于基礎提供者,只要把基礎提供者的動態庫路徑信息改成我們自己虛擬的基礎服務提供者路徑就可以了。這樣安裝的后續工作必須是把所有調用傳給原來的基礎服務提供者,所以在我們虛擬的服務提供者程序中,必須能夠檢索到原來的服務提供者路徑信息。記住,安裝之前千萬要備份原來的目錄信息。否則,一旦發生錯誤會引起網絡無法訪問。

            posted on 2009-03-10 17:19 大龍 閱讀(653) 評論(0)  編輯 收藏 引用

            很黄很污的网站久久mimi色| 亚州日韩精品专区久久久| 亚洲国产成人久久一区WWW| 精品久久久久久无码免费| 精品久久久久久无码免费| 久久精品国产国产精品四凭| 久久一区二区三区99| 综合久久一区二区三区| 色综合久久无码中文字幕| 国产亚洲精品自在久久| 国产真实乱对白精彩久久| 亚洲国产精品综合久久一线| 亚洲国产精品无码久久| 日韩亚洲欧美久久久www综合网| 久久久久女教师免费一区| 久久天天躁狠狠躁夜夜2020一| 久久99国产综合精品女同| 丁香五月综合久久激情| 久久精品一本到99热免费| 久久国产高清字幕中文| 久久久久人妻一区二区三区 | 亚洲AV无码成人网站久久精品大| 亚洲精品美女久久777777| 久久国产精品-久久精品| 四虎影视久久久免费| 国产精品久久自在自线观看| 久久成人小视频| 国产成人99久久亚洲综合精品| 无码任你躁久久久久久老妇| 国产∨亚洲V天堂无码久久久| 久久国内免费视频| 久久国产一片免费观看| 国产精品女同久久久久电影院| 日本高清无卡码一区二区久久 | 久久99精品国产一区二区三区| 久久青青草原精品国产软件 | 99精品国产在热久久无毒不卡| 欧美精品丝袜久久久中文字幕| 国产精品禁18久久久夂久| 国产精品一区二区久久精品涩爱| 久久精品女人天堂AV麻|