2011-05-07 40 views
0

我目前正試圖在C++中實現我自己的Web服務器 - 不是爲了生產性使用,而是爲了學習。Linux中的套接字 - 我如何知道客戶端已完成?

我基本上打開一個套接字,監聽,等待連接並打開一個新的套接字,從中讀取客戶端發送的數據。到現在爲止還挺好。但是我怎麼知道客戶端已經完成發送數據,而不是因爲其他原因暫時停止發送更多的數據?

我當前的例子:當客戶端發送POST請求時,它首先發送頭,然後連續兩次「\ r \ n」,然後發送請求正文。有時身體不包含任何數據。因此,如果客戶端在發送標題後暫時無法發送任何內容 - 我怎麼知道它尚未完成其請求?

這是否完全取決於使用的協議(HTTP),我的任務是根據我收到的數據找出這個問題,或者是否有類似EOF的套接字?

如果我無法從套接字中獲取必要的信息,如何保護我的程序免受故障客戶端的攻擊? (無論如何,我想我必須這樣做,因爲它可能是一個攻擊者,而不是錯誤的客戶端發送錯誤的數據。)是我唯一的選擇,直到通過協議定義完成請求或超時(由我)達成了?

我希望這是有道理的。

順便說一句:請不要告訴我使用一些庫 - 我想了解基礎知識。

回答

1

協議(HTTP)告訴您客戶端何時停止發送數據。您無法從套接字獲取信息,因爲客戶端將會等待響應。

正如你所說,你必須防範錯誤的客戶端不發送正確的請求。通常在不完整請求的情況下超時應用於讀取。如果您在30秒內沒有收到任何內容,請說關閉套接字並忽略它。

對於HTTP帖子,應該有一個標題(Content-Length),表示在標題結束後需要多少個字節。如果它的POST並且沒有Content-Length,則拒絕它。

+0

謝謝。這意味着我目前的「解決方法」實際上是要走的路。 :-) – sirion 2011-05-07 23:34:20

1

「這是否完全取決於所使用的協議(HTTP),這是我的任務是找出這我接收到的數據的基礎上,」

正確的。你可以通過谷歌找到HTTP規範; http://www.w3.org/Protocols/rfc2616/rfc2616.html

「或者是否有類似插座的EOF?」

它的行爲就像一個文件...但這不適用於此,因爲客戶端沒有關閉連接;你正在發送該連接的答覆。

+0

並非完全如此。客戶端可以使用例如半關閉連接來關閉連接。關掉()。在這種情況下,服務器在從套接字讀取時獲取EOF狀態,但仍然可以寫入套接字。 – 2011-05-07 23:25:56

+0

這將違反HTTP 1.1規範,它說客戶端應該保持持久連接。 – 2011-05-07 23:34:29

+0

RFC有關* server *的說法*保持持久連接。我不認爲RFC2616中有任何東西阻止客戶端關閉連接,當沒有更多需要發送的時候。 – 2011-05-07 23:46:12

1

使用基於文本的協議(如HTTP),您將受到客戶端的支配。大多數格式良好的POST都會有一個內容長度,以便知道有多少數據即將到來。然而,客戶端可能會延遲發送數據,或者它的以太網電纜可能已被移除或掛起,在這種情況下,該套接字將無限期地放置在那裏。如果它很好地斷開連接,那麼你會從recv()中得到一個套接字關閉事件/響應。在這種情況下

最精心設計的服務器將有一個接收超時,如果插座是閒置超過說30秒鐘,這兩點將會關閉套接字,所以資源不被行爲不端的客戶端泄露。

相關問題