天天看點

socket程式設計實作HTTP下載下傳 思路 ,未實作的 可以直接用 微軟的 wininet 庫 (轉載)...

在Windows下實作HTTP下載下傳,其實很容易,微軟已經幫我們封裝好了簡便易用的wininet庫,利用它提供的API,很容易就能開發出具備HTTP下載下傳功能的程式,不過我在這裡并不準備對wininet進行讨論,有興趣的朋友可以自行查閱MSDN或者相關資料。

我在這裡要說的,是直接使用socket程式設計,來實作HTTP的下載下傳。這種看似底層和原始的方法,雖然實作起來比較麻煩(僅僅是麻煩而已,其實很簡單),但對我們了解HTTP的工作原理和應對非Windows平台的程式設計,都有一定的幫助,是以我将這幾天自己學習的心得體會,記錄于此。本文主要涉及socket程式設計實作直接HTTP下載下傳和通過代理伺服器進行HTTP下載下傳。

HTTP消息頭

說是socket程式設計,但核心其實是對HTTP消息頭的處理,包括格式化發送,以及接受解析。一個典型的用于下載下傳的HTTP請求頭大概是這樣的:

GET /test/test.zip HTTP/1.1 -- "GET"是指令,後接要下載下傳的檔案,HTTP表示版本
Host: www.gl.gx.cn -- 主機域名
Accept: */* -- 接受任何類型的檔案
User-Agent: MyApp -- 浏覽器的類型
Connection: Keep-Alive -- 保持連接配接
-- 空行,表示請求頭結束

"--"後面的是我加的注釋,請求頭不包括這些東西。

這裡注意還有一個内容沒有列出來,但是對于HTTP下載下傳來說是比較重要的,就是"Range"項,像這樣"Range: bytes=起始位置 - 終止位置",要實作多線程下載下傳和斷點續傳就都靠他了。我并不打算詳細解說每一項内容,有興趣的可以查閱相關資料。

一個典型的伺服器傳回的響應頭如下:

HTTP/1.1 200 OK -- 響應代碼及訓示文本
Content-Length: 1679134430 -- 資料塊長度
Content-Type: application/x-zip-compressed -- 資料塊檔案類型
Last-Modified: Wed, 15 Mar 2006 13:40:59 GMT -- 修改時間
Server: Microsoft-IIS/6.0 -- 伺服器資訊
Date: Fri, 26 Sep 2008 08:42:01 GMT -- 時間
-- 空行,表示響應頭結束
XX XX XX XX XX ... -- 資料塊位元組資料

格式化的資訊清晰明了,要注意的是,請求的資料将會緊跟在表示響應頭結束的空行後面,是以這裡要自己進行拆分處理等等工作。

Socket實作HTTP下載下傳

1 - 和伺服器建立連接配接

2 - 格式化請求頭

3 - 發送請求頭

4 - 接收伺服器傳回的資料

5 - 拆分、分析響應頭

6 - 接收資料

以上就是簡要的步驟,實際程式設計的時候,還有些細節需要動動腦筋來實作,比如拆分響應頭和傳回的資料,這裡提供一種思路,接收的時候一個位元組一個位元組的接收,然後利用換行符和最後的空行來判斷響應頭和資料塊的分界點,達到拆分資料的目的。

Socket通過代理伺服器實作HTTP下載下傳

以上的方法在實際測試時,不能成功,在第一步就失敗了,無法和伺服器建立連接配接(用wininet不會有這個問題),判斷是由于公司采用代理伺服器上網造成的,無法直連外網。那如何在使用代理伺服器的情況下進行下載下傳呢?

答案其實也很簡單,上面的幾個步驟稍微修改即可,如下:

1 - 和代理伺服器建立連接配接

2 - 向代理伺服器發送對目标伺服器的連接配接請求

3 - 格式化請求頭

4 - 發送請求頭

5 - 接收伺服器傳回的資料

6 - 拆分、分析響應頭

7 - 接收資料

第一步首先和代理伺服器進行連接配接,而不是和目标伺服器,這樣就可以向代理伺服器發送HTTP請求,隻不過這次首先發送的是一個連接配接請求,如下:

CONNECT www.gl.gx.com:80 HTTP/1.1 -- 連接配接目标伺服器
Connection: Keep-Alive -- 保持連接配接
-- 空行結束

成功以後,就和目标伺服器連接配接上了,然後就和原來直連一樣了,像它發送請求就可以了。

上述通過代理進行下載下傳的方法有一個前提,就是你必須獲得代理伺服器的位址,才能和它進行連接配接。當然可以手動指定或者從配置檔案中讀取,但更多的朋友應該是希望能夠取得并使用IE的代理資訊,有兩個方法可以實作,一個是讀取系統資料庫,這個我也沒什麼研究。。。另一個就是使用wininet提供的InternetQueryOption函數,具體可以參閱MSDN,如果用到了wininet,那麼還不如連下載下傳也使用它來的友善。。。

本文隻是簡單介紹了一下HTTP直接下載下傳和代理下載下傳的原理,都是我這幾天的心得和體會,沒有提供任何源代碼,因為我也沒寫出完整的示例代碼,因為我最終決定偷懶,直接使用wininet來實作http下載下傳的功能... ╮(╯_╰)╭

轉載于:https://www.cnblogs.com/gdutbean/archive/2011/08/15/2139804.html

繼續閱讀