2009-10-19 10 views
4

我已經有一個基本的HTTP客戶端在C++中設置,到目前爲止工作正常。這是一個學校任務,所以還有很多事情要做,但我遇到了一個問題。我在一個while循環中使用recv()函數,將響應片斷重複添加到我的響應緩衝區,然後每次輸出該緩衝區。問題是,在每個響應結束時,HTTP請求也會被加入。基本的C++套接字編程中的不尋常的HTTP響應

例如,響應將是頁面源代碼的一部分,接着是「GET/HTTP/1.1 ...」,接着是下一個塊,然後是「GET ...」,並且等等。

這裏是我的相關代碼:

// Prepare request 
char request[] = "HEAD /index.html HTTP/1.1\r\nHOST: www.google.com\r\nCONNECTION: close\r\n\r\n"; 

// Send request 
len = send(sockfd, request, sizeof(request), 0); 

// Write/output response 
while (recv(sockfd, buf, sizeof(buf), 0) != 0) 
{ 
    // Read & output response 
    printf("%s", buf); 
} 

回答

7

緩衝區不是空終止,這是需要在C++字符串。當你看到「額外的GET」時,你看到的內存不應該是因爲stdlib試圖打印你的緩衝區,但從來沒有找到一個'\0'字符。

速戰速決是迫使緩衝將被終止:

int n = 1; 
while (n > 0) { 
    n = recv(sockfd, buf, sizeof(buf), 0); 
    if (n > 0) { 
     // null terminate the buffer so that we can print it 
     buf[n] = '\0'; 

     // output response 
     printf("%s", buf); 
    } 
} 
+0

有道理。謝謝! – 2009-10-20 19:15:36

0

recv一個\0字符串結束不會增加收到的緩衝區 - 它只是工作在原始的二進制。所以你的printf運行你的buf緩衝區發送(顯然結束了看你的request緩衝區)。

任一個NUL終止子增加的buf結束時,或使用putchar()一次打印緩衝器的一個字符(這兩種方法都將使得有必要存儲由recv()返回的值)。

0

該recv調用不會空終止buf;相反,它只會爲您提供從線路收到的原始數據。您需要保存recv的返回值,然後在打印之前將自己的空終止字節添加到buf中。因此,您只能請求sizeof(buf)-1個字節。

1

我懷疑這是因爲你的buf被分配在你的request正下方的內存中。當您在緩衝區上調用printf時,printf將會在找到NUL字符(標記字符串的末尾)之前儘可能多地進行打印。如果沒有一個,它會直接進入請求。一般來說,不會有一個,因爲recv用於接收二進制數據,並不知道你想要處理它的輸出字符串。

一個快速的解決將是接收操作限制sizeof(buf)-1,並明確自己添加NUL終止,使用返回的數據的大小:

while ((nr = recv(sockfd, buf, sizeof(buf), 0)) > 0) 
{ 
    buf[nr] = 0; 
    ... 
} 

當然,對於這(略)安全你需要確保你將永遠收到可打印的數據。

+0

感謝您的解釋。 – 2009-10-20 19:16:49