2011-03-04 141 views
1

我在寫一個客戶端,通過常規http multipart/form-data將文件上傳到megaupload。現在,重點本身不是互聯星空,而是他們的網絡服務器的行爲。http請求消息的邊界

即使發送完全相同的請求(用wireshark進行嗅探),curl可以毫無問題地上傳,但我的客戶卻無法發送 - 但它一直等待響應,最終在30分鐘後超時。

玩過原始套接字和strace一段時間後,原來兩者之間的唯一區別是curl發送的頭部塊只有一個調用sendto(2),然後剩下的其他調用sendto (2)。另一方面,我的客戶用寫(2)分別發送每個頭。

現在,sendto和write應該是等效的,如果send沒有指定任何標誌,並且它沒有。事實上,我使用寫入工作,但只能通過一次調用發送頭部塊。每個其他的寫入調用序列都會導致請求被阻止等待。

所以問題是:這怎麼可能? Tcp不保留消息邊界,它是一個流協議。

我能想到的唯一的事情是每個寫入/發送系統調用都會導致一個數據包被髮送,並且遠程服務器正在嗅探原始數據包並說謊是apache。

想法?或者我是一個白癡,這是一個兼容的http服務器的正常行爲? 它肯定是第一個對我表現出色的網絡服務器。

回答

0

http協議包含機制,因此客戶端/服務器可以確定消息邊界。 對於上傳的數據(POST,PUT),需要內容長度請求標頭或分塊編碼。內容長度讓服務器確切地知道從套接字接收多少個字節。一旦收到這些字節,它就會發送到另一個方向。這就是這裏的消息邊界。分塊編碼還會告訴服務器有多少字節;只是幾件。

對於響應,內容長度(或分塊編碼)是可選的。這也告訴客戶端需要多少字節;這是永久連接正常工作所必需的。如果內容長度無法確定,服務器只需關閉套接字,則客戶端知道它具有整個響應:)

+0

我知道,但這不是我問**的所有**。 – oscar 2011-04-04 09:19:23

+0

那麼那麼也許你應該澄清你的確切問題:)你問了關於http消息的界限,我給了你一個答案,試圖解釋http消息的界限。一端的send/sendto等和另一端的recv等之間沒有一對一的對應關係。 – seand 2011-04-04 20:31:34

0

這個問題指出了http和tcp之間的區別。我認爲所有的http請求頭應該在一個tcp消息中。嘗試訪問網絡服務器的調試錯誤日誌