HTTP傳輸二進制初探


【轉】HTTP傳輸二進制初探

http://www.51testing.com/?uid-390472-action-viewspace-itemid-233993

 

【轉】HTTP傳輸二進制初探

上一篇 / 下一篇  2011-04-11 04:34:49 / 個人分類:知識

從第一次接觸http協議的時候,不知是怎么回事,形成了這么一個錯誤的觀點,認為http協議是個純ASCII字符協議,也就是說在http流里是看不到二進制流的0x00值的。其實答案是:http協議里的content可以是純二進制流。
 
http://my.chinaunix.net/space.php?uid=22568683&do=blog&id=84701

關於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

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HEX_BUFFER    1024

int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Usage: %s hex_file_path\n", argv[0]);    
        exit(1);
    }
    
    FILE *fp = NULL;
    fp = fopen(argv[1], "rb");
    if(fp == NULL)
    {
        printf("open %s error. please check the path of file,and make sure you have permission to read it.\n", argv[1]);
        exit(1);
    }    
    
    unsigned char hex_buf[HEX_BUFFER];
    memset(hex_buf, 0, HEX_BUFFER);
    
    int read_count = 0;
    
    read_count = fread(hex_buf, sizeof(unsigned char), HEX_BUFFER, fp);
    if(ferror(fp) != 0)
    {
        printf("read %s error.\n", argv[1]);
        exit(1);
    }
    if(feof(fp) == 1)
    {
        printf("too large of %s, please enlarge macro HEX_BUFFER.\n", argv[1]);    
        exit(1);
    }
    fclose(fp);
    
    int i = 0;
    int j = 0;
    printf("\naddr\t0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
    for( ; i < read_count; i++, j++)
    {
        if( (j % 16) == 0)
        {
            printf("\n0x%-4x\t", j);
        }
        printf(

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM