2015-01-10 35 views
1

我創建了一個非常簡單的服務器,它接受來自瀏覽器(Safari)的http請求並響應一些轉儲HTTP響應如「Hello World」消息。句柄阻塞recv()函數之前不知道消息長度,不想使用asy I/O

我的程序在recv()函數上被阻塞,因爲它不知道客戶端(瀏覽器)是否完成發送HTTP請求和recv()是阻塞函數。 (一個非常典型的問題)

我發現的最受歡迎的答案是在發送消息之前發送消息的長度。 這個解決方案很好,但它不適用於我,因爲我無法控制客戶端發送的內容。據我所知,瀏覽器在發送真實消息之前不會發送任何消息長度。

第二個最流行的答案是使用asy I/O,如select()或poll()。但是,我個人並不認爲這是一個很好的策略,因爲一旦我已經收到客戶的所有請求消息,那麼當然,我想要進入下一步來處理請求。爲什麼我仍然會浪費我的時間和資源去等待一些永遠不會阻止的事情? (創建線程提出類似的問題)

我想出的解決方案是檢查收到的消息的大小是否等於緩衝區大小。例如,假設我將recvBufferSize設置爲32,並且請求消息的總大小爲70.然後,我將分別收到三個大小分別爲32,32和6的數據包。 我可以告訴客戶端完成發送請求,因爲最後一個數據包的大小不等於 recvBuffersize(32)。

然而,正如你可以看到,當請求消息的大小爲64/96/128出現問題......

其他方法可以像設置超時,但我不知道他們是否是好還是不好。

而且我想自己建立的所有的事情,所以我可能不會有興趣在任何庫如zeromq或Boost.Asio的

可有些人對我的做法給一些建議,或提供一些其他更好的方法解決這個問題?非常感謝!

+1

你的方法不適用於任何大小,你不能保證你的recv調用會像你的例子那樣得到32/32/6字節。你可以得到20/12/16/16/3/3。 – Mat

+1

哦,是的,你說得對。我沒有想到這一點。 我其實是在尋找最好的方法,你更喜歡哪一個?檢查之前或asy I/O的長度或超時或其他? – hclee

+0

HTTP是一個TCP協議。它實現了一個流,它不使用「消息」。您從recv()獲得的字節數完全是任意的,而不是0. –

回答

3

如果您正在實施HTTP協議,則需要研究HTTP RFC。有幾種不同的方式可以知道請求長度,從Content-length標題開始,如果客戶端使用分塊傳輸編碼,則組合的塊長度。

+0

感謝您的回覆。 然而,所有我從客戶端接收的消息是這樣的,沒有長度在所有 GET /Streaming/testlist.m3u8 HTTP/1.1 \ n 主機提到:1xx.xx.xx.xxx:8889 接受 - 編碼:gzip,deflate 接受:text/html,application/xhtml + xml,application/xml; q = 0.9,*/*; q = 0.8 User-Agent:Mozilla/5.0(iPad; CPU OS 7_0_4 like Mac OS X)AppleWebKit/537.51.1(KHTML,如Gecko)版本/ 7.0 Mobile/11B554a Safari/9537.53 Accept-Language:zh-tw DNT:1 Connection:keep-alive – hclee

+2

這就是請求。如果一個GET請求以空行結束,我相信這就是它的結束。但不要依賴我,閱讀RFC。但是我會注意到這不是有效的HTTP。行結束符應該是\ r \ n,每個標題後應該有一個。如果你不能依賴客戶,你會遇到一個比這裏可能回答的更大的問題。 – EJP

+1

爲了完整起見,請參考最新的HTTP RFC(723X):http://www.w3.org/Protocols/ – alk