一、RST包也常見(jiàn)于斷開(kāi)TCP連接
幾個(gè)月前用wireshark抓HTTP包發(fā)現(xiàn)有的網(wǎng)絡(luò)通信在結(jié)束的時(shí)候沒(méi)有使用四次握手,而是直接使用RST包。如:

在TCP協(xié)議中RST表示復(fù)位,用來(lái)異常的關(guān)閉連接。在發(fā)送RST包關(guān)閉連接時(shí),不必等緩沖區(qū)的包都發(fā)出去,直接就丟棄緩沖區(qū)的包發(fā)送RST包。而接收端收到RST包后,也不必發(fā)送ACK包來(lái)確認(rèn)?!爱惓5年P(guān)閉連接”是很常見(jiàn)的事情,特別是在使用WinHttp時(shí)。
關(guān)閉TCP連接除了常見(jiàn)的四次握手之外,還有發(fā)送RST包的方式。下邊是使用libcurl做的post測(cè)試,post成功時(shí)正常關(guān)閉,否則異常關(guān)閉。

結(jié)束TCP:四次握手圖

結(jié)束TCP:發(fā)RST包圖
二、WinHttp延遲關(guān)閉TCP連接
寫一個(gè)簡(jiǎn)單的及時(shí)退出的控制臺(tái)WinHttp Demo,可以抓包發(fā)現(xiàn)客戶端是使用RST包結(jié)束連接,而且結(jié)束連接的時(shí)間不是在WinHttpCloseHandle的時(shí)候,而是在控制臺(tái)程序退出的時(shí)候。
WinHttp有一個(gè)延遲關(guān)閉TCP連接的策略,這樣做的目的是為了復(fù)用TCP連接。實(shí)際測(cè)試的時(shí)候發(fā)現(xiàn)調(diào)用了WinHttpCloseHandle后連接沒(méi)有關(guān)閉,接下來(lái)如果繼續(xù)往服務(wù)器發(fā)送數(shù)據(jù),使用的是同一個(gè)TCP連接。不知道何時(shí)WinHttp會(huì)主動(dòng)觸發(fā)四次握手,網(wǎng)絡(luò)上沒(méi)找到這部分資料,開(kāi)發(fā)者不需要關(guān)心。從MSDN問(wèn)答區(qū)找到的資料:“WinHttp底層使用的是連接池,如果連接是由連接池自身關(guān)閉的,則會(huì)有FIN/ACK,否則就是RST包,跟客戶端何時(shí)、是否調(diào)用了WinHttpCloseHandle沒(méi)有關(guān)系?!保@么說(shuō)的話,可以猜想,連接池是進(jìn)程級(jí)別的,當(dāng)進(jìn)程退出時(shí),連接池“匆忙”的讓每一個(gè)連接發(fā)出了RST包,告訴服務(wù)器連接關(guān)閉了,說(shuō)到這兒可能會(huì)想到RST包可能丟棄了,沒(méi)關(guān)系,服務(wù)器本身有監(jiān)控策略,譬如我遇到的就有:1分鐘無(wú)通信,服務(wù)器主動(dòng)觸發(fā)四次握手關(guān)閉連接。延遲關(guān)閉是WinHttp庫(kù)自身為了復(fù)用TCP連接而做的策略,因?yàn)檫@種策略而導(dǎo)致發(fā)送RST包。
另外,WinHttp中還有一個(gè) TcpTimedWaitDelay的邏輯,但應(yīng)該跟RST包沒(méi)有什么關(guān)系,它是連接關(guān)閉多久之后TCP能釋放資源并復(fù)用,是關(guān)閉之后的事情。我嘗試修改了注冊(cè)表HKLM\System\CurrentControlSet\Services\Tcpip\Parameters中TcpTimedWaitDelay的值,并不影響WinHttp發(fā)送RST包或者四次握手所需要的時(shí)間(測(cè)試的時(shí)候等的時(shí)間超過(guò)了1分鐘,雖然我把TcpTimedWaitDelay修改為30秒了)。
本文: http://www.rzrgm.cn/cswuyg/p/3516417.html
三、相關(guān)資料
1、有人詢問(wèn)了為什么WinHttp關(guān)閉連接不是使用四次握手: http://social.msdn.microsoft.com/Forums/vstudio/en-US/e10ee4f4-c4fe-4b34-87b3-03fb7d491376/winhttpclosehandle-half-duplex-close?forum=windowssdk
2、RST包出現(xiàn)場(chǎng)景介紹:http://my.oschina.net/costaxu/blog/127394
3、TCP關(guān)閉連接后資源不及時(shí)釋放:"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
浙公網(wǎng)安備 33010602011771號(hào)