理解tcp关闭连接中的time_wait状态
首先看一下tcp關(guān)閉連接時的四次握手過程:
?
1.Client向Server發(fā)送FIN包,表示Client主動要關(guān)閉連接,然后進(jìn)入FIN_WAIT_1狀態(tài),等待Server返回ACK包。此后Client不能再向Server發(fā)送數(shù)據(jù),但能讀取數(shù)據(jù)。
2.Server收到FIN包后向Client發(fā)送ACK包,然后進(jìn)入CLOSE_WAIT狀態(tài),此后Server不能再讀取數(shù)據(jù),但可以繼續(xù)向Client發(fā)送數(shù)據(jù)。
3.Client收到Server返回的ACK包后進(jìn)入FIN_WAIT_2狀態(tài),等待Server發(fā)送FIN包。
4.Server完成數(shù)據(jù)的發(fā)送后,將FIN包發(fā)送給Client,然后進(jìn)入LAST_ACK狀態(tài),等待Client返回ACK包,此后Server既不能讀取數(shù)據(jù),也不能發(fā)送數(shù)據(jù)。
5.Client收到FIN包后向Server發(fā)送ACK包,然后進(jìn)入TIME_WAIT狀態(tài),接著等待足夠長的時間(2MSL)以確保Server接收到ACK包,最后回到CLOSED狀態(tài),釋放網(wǎng)絡(luò)資源。
6.Server收到Client返回的ACK包后便回到CLOSED狀態(tài),釋放網(wǎng)絡(luò)資源。
?
?
但是有些爬蟲服務(wù)器或者WEB服務(wù)器為什么有時候會有大量TIME_WAIT狀態(tài)出現(xiàn)?
從 上面的示意圖可以看得出來,TIME_WAIT是主動關(guān)閉連接的一方保持的狀態(tài),在發(fā)完最后一個ack狀態(tài)后,發(fā)起者的狀態(tài)會調(diào)整為TIME_WAIT。 對于爬蟲服務(wù)器來說他本身就是“客戶端”,在完成一個爬取任務(wù)之后,他就 會發(fā)起主動關(guān)閉連接,從而進(jìn)入TIME_WAIT的狀態(tài),然后在保持這個狀態(tài)2MSL(max segment lifetime ?/proc/sys/net/ipv4/tcp_fin_timeout)時間之后,徹底關(guān)閉回收資源。2MSL一般是大于30s,小于4分鐘. 最小也要30s,再大就沒啥意義了. ?為什么要這么做?明明就已經(jīng)主動關(guān)閉連接了為啥還要保持資源一段時間呢?這個是TCP/IP的設(shè)計(jì)者規(guī)定 的,主要出于以下兩個方面的考慮:
1. 收到ack,但是迷路回包的情況: 防止上一次連接中的包,迷路后重新出現(xiàn),影響干擾新連接(經(jīng)過2MSL,上一次連接中所有的重復(fù)包都會消失)
2. ack丟失的情況: 在主動關(guān)閉方發(fā)送的最后一個 ack(fin) ,有可能丟失。這時候?qū)Ψ?#xff08;被動方)會重新發(fā)fin, 如果這時主動方處于 CLOSED 狀態(tài) ,就會響應(yīng) rst 而不是 ack。所以主動方要處于 TIME_WAIT 狀態(tài),而不能是 CLOSED 。另外這么設(shè)計(jì)TIME_WAIT 會定時的回收資源,并不會占用很大資源的,除非短時間內(nèi)接受大量請求或者受到攻擊。
如果接收到rst,也就是tcp連接重置,服務(wù)端應(yīng)用有報錯。?
reset報文發(fā)送場景:
RST的標(biāo)志位,這個標(biāo)識為在如下幾種情況下會被設(shè)置。
1.當(dāng)嘗試和未開放的服務(wù)器端口建立tcp連接時,服務(wù)器tcp將會直接向客戶端發(fā)送reset報文
2.雙方之前已經(jīng)正常建立了通信通道,也可能進(jìn)行過了交互,當(dāng)某一方在交互的過程中發(fā)生了異常,如崩潰等,異常的一方會向?qū)Χ税l(fā)送reset報文,通知對方將連接關(guān)閉
3.當(dāng)收到TCP報文,但是發(fā)現(xiàn)該報文不是已建立的TCP連接列表可處理的,則其直接向?qū)Χ税l(fā)送reset報文
4.ack報文丟失,并且超出一定的重傳次數(shù)或時間后,會主動向?qū)Χ税l(fā)送reset報文釋放該TCP連接
另外我們做大量api請求時會遇到下面的問題.?Broken pipe和Connection reset by peer ?. ? 這其實(shí)也是reset的報錯一種.
總結(jié)
以上是生活随笔為你收集整理的理解tcp关闭连接中的time_wait状态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: curl模拟delete/put/pos
- 下一篇: Ansible中文权威指南