WinInet 和 WinHttp 有何區別?

自制工具   翰華Box:https://hanhuabox.lanzous.com/b00zjq9uf

翰華Box - 開發日誌:https://blog.csdn.net/qq_41517936/article/details/106409456

目錄

背景

編程模型

代理支持

HTTP Headers以及Cookie的支持

WinInet 和 WinHttp 的區別總結


背景

       WinInetWinHttp是windows平臺下提供了兩套獨立的網絡庫,按照微軟官方的說法, WinInet的優勢在於client-端的應用,而WinHttp更適用於server-端編程。從名稱上我們可以看出WinHttp在Http協議應用方面要比WinInet更加專業,WinInet支持的協議包括Gopher\HTTP\HTTPS\FTP較爲雜亂,而WinHttp庫專門是爲HTTP\HTTPS服務的

       WinInet支持如此多協議的原因在於其自身是IE瀏覽器的網絡層,所以它必須提供全方位的服務,包括各種協議的封裝以及Cache機制。同時WinInet API的行爲也被IE的設置所影響,具體表現爲:用戶通過“IE菜單->工具->連接->添加”可以爲WinInet API指定專用的網絡連接, autodialing服務沒有從WinInet模塊中分離出來;用戶通過“IE菜單->工具->連接->局域網設置”可以爲特定協議請求設置代理服務器,這一設置會影響到WinInetAPI 的行爲;如果代理服務器需要用戶/密碼驗證,則直接讀取IE默認代理配置會使WinInet API訪問失敗,IE代理設置中不保存驗證信息;WinInet API提供了持久化Cookie的機制,連接請求發起前必須手動清空Cookie,否則它們會在後續的請求中出現;WinInet的Cookie設置是針對特定URL而不是某次特定的請求,這種方式適用於IE瀏覽器應用,但對於我們目前的產品需求而言,降低了安全性

      WinHttp程序庫不存上述問題,它是專門爲Http應用量身定製的網絡庫。

       在平臺要求方面,WinInet程序庫要求客戶運行在windows 2000 以及後續版本,而WinHttp程序庫要求客戶運行在Windows XP,Windows 2000 sp3以及後續版本,對於大多數Windows平臺上的Http應用,官方推薦使用WinHttp,並給出了將現有WinInet API應用向WinHttp API轉換的解決方案。

編程模型

       利用WinInet或WinHttp進行Http協議編程時,有三種對象非常重要,即Session, Connection以及Request。使用者創建一個Session通知WinInet或WinHttp模塊初始化內部的數據結構,每個Session有自己的一些屬性,如代理服務器的設置;發送Http請求時標識自己名稱的User-Agent Http頭部;標識Session是否支持異步請求的標記字段等等。在一個Session之上可以存在多個Connection對象,每個Connection對應於一個目標服務器和端口號。在一個Connection之上可以存在多個Request對象,每個Request對應於Connection之上的URI資源地址以及HTTP動作(GET或POST等)。當使用者得到一個合法Request對象的句柄後,就可以與對應的服務器進行Http交互了。下圖分別描述了WinInet和WinHttp實現的Http協議棧的主要操作函數。

       網絡交互是一個耗時的操作,針對這一特點,WinInet和WinHttp作爲Htpp協議的Windows網絡實現庫,提供了兩種編程模型:即同步編程模型異步編程模型

       同步編程模型可以理解爲在調用API的線程中啓動網絡請求並進入到阻塞狀態,當網絡請求返回或者內部發生錯誤時,阻塞被解除,程序繼續順序執行。而在異步編程模型中,當調用API的線程發出請求時,在WinInet或WinHttp模塊內部會啓動一個工作線程來完成耗時的網絡操作,請求的結果通過回調報告給調用者線程所註冊的函數,但是回調函數的執行環境還是在工作線程中,所以需要對臨界區做互斥保護。異步編程模型比同步編程模型更靈活,工作線程的管理工作也在模塊內部被透明的完成,譬如同時啓動大量的請求,WinInet和WinHttp都會將請求排隊,而不是立即啓動數量相同的工作線程,破壞系統的整體穩定性。雖然WinInet和WinHttp都提供了異步編程模型,但兩者在易用性上卻有很大的區別,WinHttp API使用起來更加的統一和一致,而WinInet由於利用Session/Connection/Request的框架支持多種協議,雖然提供了豐富的功能,但卻損失了易用性。譬如WinInet中創建Connection對象的API中有username和password的參數,對於Http Connection顯然是多餘的或者語義不清晰,但又是必要的,因爲WinInet中利用同樣的函數創建Ftp Connection,畢竟WinInet太古老了,作爲IE的網絡層,在那個年代,此種設計也許是可以被接受的。

代理支持

       WinInet和WinHttp都支持代理服務器的設置,但正如前文提到的WinInet API的代理設置會受到本地IE瀏覽器設置的影響,而WinHttp編程操作性更強、外部依賴性更小

       WinInet提供了自動撥號的功能,如果IE設置了特定了網絡連接,當調用WinInet API進行網絡請求時,若指定的網絡連接不可用,就會啓動自動撥號程序,即使有本地有可用的網絡連接,WinInet也不會使用;但對於WinHttp來說就不會存在這種情況,它可以智能的選擇本地可用的網絡連接,而不被外部設置所影響。WinInet支持自動代理檢測以及代理檢測腳本,對應於IE配置對話框中的“自動配置”面板,同時提供了相關的API接口。WinHttp API中也提供了對自動代理的支持。

      在WinInet API中可以對四種協議設置代理服務器,它們分別爲HTTP/HTTPS/FTP/SOCKS4,而在WinHttp API中僅能對HTTP/HTTPS設置代理服務器。不過,對於僅僅使用HTTP協議的應用來說,這不是WinHttp的劣勢,因爲其本身僅僅支持HTTP/HTTPS。下圖爲IE的代理設置對話框。

 

      在代理設置的粒度方面,WinInet代理需要設置在Session級別,而WinHttp的代理可以設置在Request級別,從而增加了靈活性。

        WinInet 和 WinHttp都提供了工具,可以將代理配置保存在註冊表中,只需在創建Session時指定相關的標識,就可以使用全局代理。但當IE配置了某些連接或代理項目後,WinInet API的行爲就有些詭異或莫名其妙的連接不上,所以纔有了本篇總結報告,結論是推薦使用WinHttp來代替WinInet。

HTTP Headers以及Cookie的支持

    WinInet 和 WinHttp都提供HTTPHeader的設置接口,操作對象是Request句柄,也就是說,針對每次Http請求,編程人員可以根據需求設置附加的Http頭。Cookie在Http協議中也是以HTTPHeader的形式存在的。在瀏覽器中,Cookie相關的Http頭對象被進行了特殊的處理,通過分析Cookie的有效期(Http請求的返回包通過Set-Cookie來對Cookie以及有效期進行設置),對其進行持久化操作或存儲在內存中。當再次和服務器進行交互時,同一url域下的有效Cookie會以Http頭的形式發送給服務器。

      WinInet作爲IE瀏覽器的網絡層繼承了瀏覽器對Cookie的處理方式,並且支持Cookie的持久化利用InternetSetCookie對特定的Url域設置Cookie,一旦設置成功,後續對此Url的Http訪問都會攜帶被設置的Cookie,除非用戶手動清除。

      在WinHttp中並沒有提供對Cookie設置的相關接口,如果服務器對Http請求方的Cookie數據有需求,那麼編程人員需要利用設置Http 頭的編程接口,對於特定的Reqeust對象進行設置

以上內容取自百度文庫(個人標記重點):https://wenku.baidu.com/view/f1b56009844769eae009ed69.html

WinInet 和 WinHttp 的區別總結

WinInet支持的協議包括Gopher\HTTP\HTTPS\FTP較爲雜亂,而WinHttp庫專門是爲HTTP\HTTPS服務的

WinHttp就是WinInet 的升級版。
WinHttp訪問的速度 比 WinInet 快(術業有專攻)。
而且還有 WinInet 在多線程裏面很容易崩。
還有一點就是 WinInet 訪問的時候會帶上 本地IE的Cookie ,而WinHttp不會

WinInet:post成功之後,打開IE,你會發現帳號登陸了
WinHttp:post成功之後,打開IE,你會發現帳號沒有登陸了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章