簡體   English   中英

收到應用程序級別的確認后,我們可以重新設置TCP連接嗎?

[英]Can we just reset TCP connections after an application level acknowledgement has been received?

我正在研究重置TCP連接,以解決TIME_WAIT問題。


讓我們以下面的請求-應答協議為例:

  1. 客戶端打開與服務器的連接。
  2. 客戶端發送一個請求。
  3. 服務器回復。
  4. 服務器關閉。
  5. 客戶端也關閉。

這會在服務器上導致TIME_WAIT狀態。 作為一種變化,客戶可以先關閉。 然后, TIME_WAIT到達客戶端。

我們不能用以下內容代替步驟4和5嗎?

  1. 客戶端重置。
  2. 服務器根據傳入的重置進行重置。

這似乎是避免TIME_WAIT問題的一種方法。 服務器已通過發送答復來證明已接收並​​處理了請求。 客戶收到回復后,連接將消耗大量資源,並且可以斷開連接。

這是一個好主意嗎?

唯一的問題是服務器不知道客戶端是否收到了所有內容。 情況是模棱兩可的:客戶端連接是由於客戶端收到了整個答復而重置的,還是由於其他原因而重置了?

添加應用程序級別的確認不能可靠地解決問題。 如果客戶端確認,然后立即中止關閉,則客戶端不能確定服務器是否收到該確認,因為中止關閉會丟棄未傳輸的數據。 而且,即使數據被發送,由於連接不可靠,它也可能丟失。 並且一旦連接中止,TCP堆棧將不再提供該數據的重傳。

正常的,非繁瑣的情況通過讓客戶端和服務器TCP堆棧獨立於應用程序執行來照顧最終儀式來解決該問題。

因此,總而言之,如果我們關心的只是客戶端收到其答復,並且服務器不關心該請求是否成功,則中止是可以的:在許多情況下這不是不合理的假設。

我懷疑您對服務器上的TIME_WAIT錯誤。

如果對單個基於TCP的客戶端-服務器事務遵循以下順序,則TIME_WAIT在客戶端:

  1. 客戶端啟動與服務器的活動連接

  2. 客戶端向服務器發送請求。

  3. 客戶端半關閉連接(即發送FIN)

  4. 服務器讀取客戶端請求,直到EOF(FIN段)

  5. 服務器發送答復並關閉(生成FIN)

  6. 客戶閱讀對EOF的回復

  7. 客戶關閉。

由於客戶端是第一個發送FIN的用戶,因此進入TIME_WAIT。

訣竅是,客戶端必須首先關閉發送方向,然后服務器通過讀取整個請求來對其進行同步。 換句話說,您將流邊界用作消息邊界。

您要嘗試做的是純粹在應用程序協議內部進行請求框架,而根本不使用TCP框架。 也就是說,服務器在客戶端未關閉的情況下識別出客戶端消息的結尾,同樣,客戶端在不關心讀取到結尾的情況下解析服務器響應。

即使您的協議是這樣的,您仍然可以進行半關閉舞蹈程序的動作。 服務器在檢索到客戶端請求之后,仍然可以繼續從其套接字讀取並丟棄字節,直到讀取所有內容為止,即使不需要字節也是如此。

我會說:不,這不是一個好主意。 每種可能的解決方案都以TIME_WAIT最終解決的相同“問題”結束:甲方如何確認連接的結束(或確認另一方對連接結束的最終確認),知道乙方得到了確認? 答案總是:它不可能永遠知道這一點。

你說:

服務器通過發送答復來證明它已接收並處理了請求

...但是如果該回復丟失了怎么辦? 服務器現在已經清理了會話的那一部分,但是客戶端將永遠等待該回復。

乍一看,TCP狀態機可能看起來過於復雜,但是這樣做的確有充分的理由。

暫無
暫無

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

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