2011-05-21 68 views
4

我寫了兩個簡單的程序服務器和一個使用C++(Linux)中的套接字的客戶機。最初它是一個示例客戶端 - 服務器應用程序(回顯消息發送和接收答案)。接下來,我更改了客戶端以實現HTTP GET(現在我不再使用我的示例服務器)。它可以工作,但是無論我設置了什麼緩衝區大小,客戶端都只能收到1440字節。我想要整個頁面進入緩衝區。我認爲這與TCP屬性有關,我應該在客戶端代碼中實現某種循環來捕獲答案的所有部分。但我不知道我該做什麼。如何通過套接字接收1440多個

這是我的代碼:

... 
int bytesSent = send(sock, tmpCharArr, message.size()+1, 0); 
// Wait for the answer. Receive it into the buffer defined. 
int bytesRecieved = recv(sock, resultBuf, 2048*100, 0); 
... 

2048 * 100是一個緩衝區的大小,我覺得這是綽綽有餘了用於測試的相對較小的網頁更多。但正如我所提到的,我只收到1440字節。

當服務器的響應大於1440字節時,我可以用recv()函數調用來捕獲所有回覆「部分」?

在此先感謝。

回答

6

緩衝區大小取決於您控制範圍之外的因素(路由器,ADSL鏈路,IP堆棧等)。傳輸大量數據的標準方式是重複撥打recv()

+0

是的,其實我預料到了這一點。但是,我怎麼知道我應該多少次調用recv()? – 2011-05-21 06:33:46

+1

@ danny_23:直到你有足夠的數據。在web服務器的情況下,它會傳遞給你一個內容長度的頭部,它告訴你何時停止讀取正文,或者在完成時會關閉套接字,在這種情況下,直到'recv()'返回零。 – 2011-05-21 06:36:29

+0

@ danny_23:反覆直到客戶告訴你他們已經完成。 – Johnsyweb 2011-05-21 06:36:56

1

HTTP通過TCP工作,並且瞭解TCP套接字的工作情況,您必須更好地將它們視爲流而不是數據包。

爲了更清楚,看我以前的帖子:recombine split TCP packet with flash sockets

至於爲何僅收到1400(左右)字節,你要明白MTU和碎片。綜上所述,MTU(最大傳輸單元)是網絡傳輸某個最大大小的單個數據包的能力。整個網絡的MTU是所有涉及路由器的最低MTU。如果您嘗試發送大小超過該網絡MTU的單個數據包,則碎片將導致數據包分裂。

爲了更好地理解MTU和破碎化,閱讀:http://www.miislita.com/internet-engineering/ip-packet-fragmentation-tutorial.pdf

現在對於如何在緩衝區接收整個頁面,一個備選方案是保持通話recv()和附加您在緩衝區中獲取數據,直到recv()返回zero。這將起作用,因爲通常情況下,Web服務器在向您發送響應後將關閉TCP連接。但是,如果Web服務器未關閉會話,則此技術將無法工作(可能保留配置)。

因此,正確的解決方案是繼續接收,直到您收到HTTP頭。查看並確定整個HTTP響應的長度(Content-Length:),然後您可以繼續接收,直到您收到您應該接收的確切字節數。

相關問題