HTTP的RST包與WinHttp延遲關閉TCP連接


一、RST包也常見於斷開TCP連接 

    幾個月前用wireshark抓HTTP包發現有的網絡通信在結束的時候沒有使用四次握手,而是直接使用RST包。如:

      在TCP協議中RST表示復位,用來異常的關閉連接。在發送RST包關閉連接時,不必等緩沖區的包都發出去,直接就丟棄緩沖區的包發送RST包。而接收端收到RST包后,也不必發送ACK包來確認。“異常的關閉連接”是很常見的事情,特別是在使用WinHttp時。

     關閉TCP連接除了常見的四次握手之外,還有發送RST包的方式。下邊是使用libcurl做的post測試,post成功時正常關閉,否則異常關閉。

結束TCP:四次握手圖

結束TCP:發RST包圖

二、WinHttp延遲關閉TCP連接

          寫一個簡單的及時退出的控制台WinHttp Demo,可以抓包發現客戶端是使用RST包結束連接,而且結束連接的時間不是在WinHttpCloseHandle的時候,而是在控制台程序退出的時候。

        WinHttp有一個延遲關閉TCP連接的策略,這樣做的目的是為了復用TCP連接實際測試的時候發現調用了WinHttpCloseHandle后連接沒有關閉,接下來如果繼續往服務器發送數據,使用的是同一個TCP連接。不知道何時WinHttp會主動觸發四次握手,網絡上沒找到這部分資料,開發者不需要關心。從MSDN問答區找到的資料:“WinHttp底層使用的是連接池,如果連接是由連接池自身關閉的,則會有FIN/ACK,否則就是RST包,跟客戶端何時、是否調用了WinHttpCloseHandle沒有關系。”,這么說的話,可以猜想,連接池是進程級別的,當進程退出時,連接池“匆忙”的讓每一個連接發出了RST包,告訴服務器連接關閉了,說到這兒可能會想到RST包可能丟棄了,沒關系,服務器本身有監控策略,譬如我遇到的就有:1分鍾無通信,服務器主動觸發四次握手關閉連接。延遲關閉是WinHttp庫自身為了復用TCP連接而做的策略,因為這種策略而導致發送RST包。

      另外,WinHttp中還有一個 TcpTimedWaitDelay的邏輯,但應該跟RST包沒有什么關系,它是連接關閉多久之后TCP能釋放資源並復用,是關閉之后的事情。我嘗試修改了注冊表HKLM\System\CurrentControlSet\Services\Tcpip\Parameters中TcpTimedWaitDelay的值,並不影響WinHttp發送RST包或者四次握手所需要的時間(測試的時候等的時間超過了1分鍾,雖然我把TcpTimedWaitDelay修改為30秒了)。

本文: http://www.cnblogs.com/cswuyg/p/3516417.html

三、相關資料

1、有人詢問了為什么WinHttp關閉連接不是使用四次握手: http://social.msdn.microsoft.com/Forums/vstudio/en-US/e10ee4f4-c4fe-4b34-87b3-03fb7d491376/winhttpclosehandle-half-duplex-close?forum=windowssdk

2、RST包出現場景介紹:http://my.oschina.net/costaxu/blog/127394

3、TCP關閉連接后資源不及時釋放:"TCP does not release a connection or reuse its resources until the connection has remained closed for a period specified by the value of the TcpTimedWaitDelayentry"   http://technet.microsoft.com/en-US/library/cc938178


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM