簡體   English   中英

寫入數據后向套接字發送錯誤響應

[英]Sending error response to socket after data has been writen

我有一個使用c編寫HTTP服務器的任務。 服務器讀取請求並相應地發送響應。 當請求是文件的路徑時,我需要讀取文件內容並將其作為響應發送給客戶端。

文件大小沒有限制,所以我按塊讀取它並按塊發送響應。 老師說如果在已經寫完部分響應后recv / send調用失敗,則可以關閉連接並繼續,但應通知客戶端響應未正確發送。

我的問題是,假設發送調用失敗,嘗試發送響應未正確發送的消息可能會再次失敗。 如何通知客戶端發送響應時出錯?

你的老師並不是說你的服務器應該通知客戶端,而是應該(已經)通過recv()通知客戶端,因此除了關閉連接之外,你在服務器端沒有什么特別需要做的。

1也就是說,假設你的老師沒有困惑。

你的老師的陳述沒有說明意義,或含糊不清。 HTTP狀態代碼位於有效負載之前。 如果寫入有效負載時出錯,則除了重置連接之外沒有辦法通知對等方,如果您知道如何執行此操作,或者由於發送錯誤(最可能)已經發生這種情況。

老師說如果在已經寫完部分響應后recv / send調用失敗,則可以關閉連接並繼續,但應通知客戶端響應未正確發送。

首先,一旦你開始send()響應,你就不應該調用recv() ,直到響應完全發送完畢。 在當前響應完成之前,您無法啟動recv()的下一個請求。

其次,如果recv()send()因任何原因失敗,則必須關閉當前連接,沒有其他選項。

我的問題是,假設發送調用失敗,嘗試發送響應未正確發送的消息可能會再次失敗。 如何通知客戶端發送響應時出錯?

你不能,也不應該嘗試。 如果這是你的老師告訴你要做的事情,那么要么你誤解了老師的實際說法,要么你的老師不理解HTTP的實際工作方式。

發生連接故障時,關閉連接是唯一的選擇。 如果客戶端尚未失敗,它將(最終)檢測到關閉(或超時),並且由於未完全收到響應這一事實將知道響應失敗。 它如何檢測響應的結束取決於響應的格式(有關詳細信息,請參閱RFC 2616第4.4節“消息長度 ”)。

要小心 - 有一個條件,連接關閉不是響應失敗的指示! 如果服務器:

  1. 沒有響應HEAD請求;

  2. 沒有回復1xx204304回復代碼;

  3. 不發送Content-LengthTransfer-Encoding: identity響應頭;

  4. 不是以multipart/byteranges格式發送響應主體;

然后,服務器正常關閉連接(服務器使用shutdown(SD_SEND)shutdown(SD_BOTH)故意關閉,發送一個啟用了FIN標志的TCP數據包完成響應。在某些平台上,包括Windows, close() / closesocket()將執行隱式關閉,但最好是顯式的)。

客戶端必須查看響應頭以檢測響應的發送方式並采取相應措施。 如果它落入最后一個條件,則只有優雅的斷開才能被視為成功。 任何其他類型的斷開都將被視為失敗。 因此,服務器應始終至少發送Content-LengthTransfer-Encoding標頭。 它避免了斷開連接代表的模糊性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM