在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