2012-07-23 78 views
4

我正在開發一個需要分析塊式HTTP傳輸的客戶端。我用頭撞牆,試圖找出以下錯誤,並希望有人能夠更快地發現我的錯誤。總結一下這個問題:似乎客戶端並沒有收到所有的數據塊,從而搞砸了剩下的過程。提前致謝!C解析HTTP分塊傳輸編碼響應

while(cflag){ 
    pfile_chunk = malloc(CHUNK_SIZE+1); 
    memset(pfile_chunk, 0, CHUNK_SIZE); 
    cPtr = pfile_chunk; 
    cPtr2 = NULL; 
    k=0; 
    while(*(cPtr-1) != '\n'){ 
     k++; 
     recv(sock, cPtr, 1, 0); 
     cPtr = pfile_chunk+k; 
    } 
    cPtr2 = strchr(pfile_chunk, '\r'); 
    *cPtr2 = '\0'; 
    sscanf(pfile_chunk, "%x", &l); 
    if(l == 0) 
     break; 
    printf("\nServer wants to deliver %ld bytes.\n", l); 
    pfile_chunk = realloc(pfile_chunk, l+1); 
    memset(pfile_chunk, 0, l); 
    recv(sock, pfile_chunk, l, 0); 
    fputs(pfile_chunk, f); 
    printf("GOT THIS, SIZE %ld:\n%s\n", strlen(pfile_chunk), pfile_chunk); 
    //get next \r\n bytes. 
    recv(sock, NULL, 2, 0); 
} 
+0

我爲這些草率的代碼事先道歉,這或多或少是我嘗試許多不同事情的結果。 – 2012-07-23 22:05:43

+0

你介意發佈你的最終清理代碼嗎?我也在爲這個任務而努力。不知道如何協調從緩衝區讀入的內容與實際的HTTP塊。在解析塊之前是否存儲整個HTTP響應? – 2012-08-24 09:02:03

回答

5

最起碼,你應該檢查的recv返回值,看看是否你得到你期望得到的字節數。

由於系統調用將在您撥打電話時返回套接字接收緩衝區中可用的任何內容,因此網絡上的短讀取肯定是可行的。

執行一個循環,直到讀完整個塊,或將MSG_WAITALL標誌傳遞給最後一個參數中的recv。但是,您仍然需要檢查recv中的錯誤。

ssize_t r = recv(sock, pfile_chunk, l, MSG_WAITALL); 
if (r < l) { 
    /* check for errors ... */ 
} else { 
    /* got the data */ 
} 
+0

謝謝先生,我甚至沒有考慮發送/ recv標誌。錯誤檢查並不存在,因爲我一直處於這種急速移動的潦草代碼之中。欣賞它!有人+1這個人,我沒有所需的聲譽。 – 2012-07-24 00:51:48

2

看起來好像你在你的while循環檢查的第一個提領將您的數組,這很可能是不被期望的行爲開始之前訪問。希望該內存位置通常不會包含\n。這可能會搞砸你的read。我希望它可能包含一些與您的malloc有關的信息,這可能不會是\n,所以您可能永遠不會看到問題。

另外,希望您可以相信套接字的另一端在給您\n之前不要發送超過CHUNK_SIZE+1。否則,它可能會出現故障。不過,通常情況下,我希望發件人只需發送10個或更少的ASCII數字字符和一個CRLF作爲塊頭,但理論上它們可以發送一堆長塊擴展頭字段。

除此之外,user315052已經發現了更重要的問題,您應該告訴recv方法等待您請求的所有數據,或者檢查它實際讀取的數據量。