[英]Why is there TCP RST packet after sending a string and closing a socket
[英]Python - Read remaining data from socket after TCP RST
我正在使用以下用例實現文件傳輸協議:
在這種情況下,在服務器端(在 Windows 上運行的 Python)發生的事情是我在將數據發送到客戶端時捕獲了 ConnectionResetException(這是正常的,客戶端已斷開套接字)。 我想讀取客戶端發送的最新數據(用於中止調用的消息),但調用 mysocket.recv() 仍然會引發 ConnectionResetException。
通過wireshark 捕獲,我可以清楚地看到消息是在TCP 斷開之前由客戶端正確發送的。
有什么想法嗎? 謝謝!
虛擬現實
為了了解如何處理這種情況,您需要了解 TCP 連接是如何關閉的(參見,例如this )以及套接字 API 如何與干凈關閉相關(沒有失敗,參見this )。
您的客戶端很可能會調用 close 來終止連接。 這樣做的問題是,套接字接收隊列中可能有未讀數據或從另一端很快到達的數據,您將無法再讀取,這基本上是一種錯誤情況。 為了向另一端發出無法將發送的數據傳遞給接收應用程序的信號,發送復位(從技術上講,根據 RFC,“應該發送”)並且 TCP 連接異常終止。
您可能認為啟用 SO_LINGER 會有所幫助(很多很多位已經溢出,所以我不會進一步詳細說明),但它不會解決客戶端未讀取數據導致重置的問題。
客戶端需要改為調用shutdown(SHUT_WR)
來指示它已完成發送,然后繼續調用recv()
直到它讀取到0 字節指示另一端已完成發送。 然后您可以調用close()
。
請注意,Python 2 插槽文檔指出
根據平台,關閉連接的一半也可以關閉另一半(例如,在 Mac OS X 上,shutdown(SHUT_WR) 不允許在連接的另一端進行進一步讀取)。
這對我來說聽起來像是一個錯誤。 為了解決這個問題,您必須發送您的取消消息,然后繼續閱讀,直到您獲得 0 個字節,以便您知道服務器收到了取消消息。 然后您可以close
套接字。
Python 3.8 文檔沒有做出這樣的免責聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.