【轉】HTTP傳輸二進制初探
http://www.51testing.com/?uid-390472-action-viewspace-itemid-233993
【轉】HTTP傳輸二進制初探
上一篇 / 下一篇 2011-04-11 04:34:49 / 個人分類:知識
關於HTTP傳輸ASCII文本內容的過程相信大家都應該容易理解,因為HTTP請求頭和響應頭都是以ASCII文本方式傳輸的。而對於HTTP傳輸二進制流的相關細節,其實沒有我想象中的那么復雜,以前學習POP3和SMTP(這兩個都是郵件傳輸協議)的時候,知道他們都只能傳輸ASCII文本,如果要在郵件中加入附件,如一張圖片(圖片文件就是二進制文件)那就得先對圖片文件轉碼,即將郵件協議不能傳輸的二進制數據流轉換成可被郵件協議傳輸的ASCII數據流,其中用的最多的轉換就是BASE64編碼轉換。其實BASE64編碼轉換也同樣適合於HTTP協議,只有你在轉換后將HTTP響應頭中的Transfer-Encoding設置為base64,當然如果客服端瀏覽器不支持base64編碼那這種轉換也是徒勞的,不過幸好現在幾乎所有瀏覽器都支持BASE64(你能用瀏覽器查看郵件中的附件就是證據)。
不過話又回來,既然HTTP能夠直接支持二進制的數據流傳輸,那我們又何必繞着彎子,走冤枉路呢?
如果你和一樣,也對HTTP能直接傳輸二進制感到疑問,那么下面的內容會很對你胃口。
我們以一張圖片的傳輸來說明這個問題:
http://gimg.baidu.com/img/gs.gif 這是 百度主頁上一張非常小的圖片的鏈接地址 即右側
圖片
我們用到的工具有:
Firefox 瀏覽器
Firebug 一個非常不錯的 web調試器,Firefox插件
Ethereal 網絡抓包工具
如果你對上面三個工具不是很了解,建議你先去google一下。然后再來閱讀。
下面是我們在Firefox地址欄里面輸入http://gimg.baidu.com/img/gs.gif 回車后,Firefox默默地為我們做的事情。關於HTTP通行的細節請參閱我以前的 文章
http://blog.chinaunix.net/u3/104217/showart.php?id=2075210
http://p.99081.com/unix/http_protocol_summary.html
GET /gs.gif HTTP/1.1
Host: gimg.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
當Firefox發出該請求后,服務器接收並分析該請求,經分析后得出客服端瀏覽器請求的文件(或者說頁面)為/img/gs.gif (第一個斜桿代表服務器根目錄),於是服務器(百度的HTTP服務器為Apache)從服務器主機的硬盤(或者直接從內存的緩沖區)中讀出該圖片(注意哦,直接讀二進制流),並將其拼接到HTTP響應頭后,然后把這片數據(我指的是HTTP響應頭加上圖片的二進制數據)拷貝到TCP的發送緩沖區(也就是調用send函數)。
下面即位客服端收到的從服務器端發來的數據流:
我們還是先來分析一下響應頭
HTTP/1.1 200 OK
Date: Tue, 27 Oct 2009 13:43:15 GMT
Server: Apache
Last-Modified: Fri, 11 Aug 2006 04:20:15 GMT
Accept-Ranges: bytes
Content-Length: 91
Cache-Control: max-age=315360000
Expires: Fri, 25 Oct 2019 13:43:15 GMT
Connection: close
Content-Type: image/gif
注意最后一個字段 Content-Type:image/gif 這說明傳輸的是一個image對象,該對象為gif格式。另外我們還有記下Content-length:91 這說明傳輸的數據(即gs.gif圖片)的大小為91個字節,此外我們還發現響應頭中並沒有Transfer-Encoding這個字段,這說明傳輸的數據沒有經過任何形式的編碼轉換,傳輸的就是源文件的內容。
請認真查看上圖中藍底部分,在藍底的最后那一行,有兩個連續的 0d 0a 0d 0a ,這說明HTTP響應頭已經結束,接下來的內容為傳輸的文件。好啦,那接下來當然是要分析傳輸的文件到底是啥東西了。請看下圖
圖中藍底的部分即為傳輸的數據流(即傳輸的文件),這些是什么東西,我也搞不懂,(估計只有搞圖片壓縮算法的人能夠看得懂),不過沒關系,我們可以先把圖片保存在本地,然后用一個十六進制查看軟件打開該圖片,即可知道其中的奧秘。
下面是用UltraEdit打開該圖片后的截圖
請比較一下上面兩張圖片是不是有很多相同的地方呀,其實上面兩張圖中,第一張中的藍底部分就是第二張中的數據。這下你應該明白了吧,其實HTTP傳輸的就是圖片文件的二進制編碼,Apache沒有對二進制文件進行任何形式的編碼轉換。我們還可以計算一下這個圖片的大小:16 * 5 + 11 = 91 (也就是 0x5a – 0x00 = 0x5a),正好和HTTP響應頭中的Content-Length相等。
如果沒有UltraEdit等十六進制編輯器,我寫了個簡單的程序以供查看,下面是源碼:
check_hex.c
|