1. 程式人生 > >tcp連線關閉詳解和注意事項

tcp連線關閉詳解和注意事項

注:tcp關閉連線不區分客戶端和服務端,哪一埠可以主動發起關閉連線請求。所以為了描述方便,描述中的“主動方”表示主動發起關閉連線一方,“被動方”表示被動關閉連線一方。 1. tcp關閉連線狀態轉換 tcp 連線關閉詳解 - 網易杭研後臺技術中心 - 網易杭研後臺技術中心的部落格  
上圖是tcp連線主動關閉端的狀態轉換圖: (1)應用層呼叫close函式發起關閉連線請求 (2)傳送FIN到對端,關閉寫通道,自己進入FIN_WAIT1狀態 (3)等待對端的確認ACK到來,接受到ACK後進入FIN_WAIT2狀態;如果在超時時間內沒有收到確認ACK直接進入CLOSED狀態 (4)如果在FIN_WAIT1狀態時收到了對端的FIN則進入CLOSING狀態(雙發都發出了關閉連線請求) (5)在FIN_WAIT2接受到了對端FIN後進入TIME_WAIT狀態;如果在超時時間內沒有收這個FIN則直接進入CLOSED狀態 (6)在TIME_WAIT狀態等待2個MSL(2個報文最長存活週期)後進入CLOSED狀態 tcp 連線關閉詳解 - 網易杭研後臺技術中心 - 網易杭研後臺技術中心的部落格
  上圖是tcp連線被動關閉方的狀態轉換圖 (1)收到對端FIN後,關閉讀通道進入CLOSE_WAIT狀態 (2)在CLOSE_WAIT狀態等待應用層呼叫close函式關閉連線 (3)如果在超時時間內呼叫了close,則進入LAST_ACK狀態;否則直接進入CLOSED狀態 (4)在LAST_ACK狀態,傳送FIN到對端並等待對端的確認ACK (5)如果在超時時間內收到了確認ACK則進入CLOSED狀態,否則直接進入CLOSED狀態 2. 狀態分析 2.1 FIN_WAIT1 這個狀態在實際的工作中很少見。主動方呼叫close函式關閉連線後立刻進入FIN_WAIT1狀態,此時只要收到對端確認ACK後馬上會進入FIN_WAIT2狀態。因為對端確認ACK是TCP協議棧自己控制的,所以很快就會發出。出現場景:主動方等待ACK過程中網路斷掉了,導致長時間收不到ACK,主動方就會停留在CLOSE_WAIT1狀態上(超時時間:一般預設60s超時)。此時我們可以使用netstat -anpt 命令看到這種狀態。 NOTE:這個狀態如果超時,將直接進入CLOSED狀態。關於超時時間你可能需要了解:tcp_fin_timeout這個配置引數。
2.2 FIN_WAIT2 這個狀態比較常見。主動端在等待對端FIN到來過程中,會一你直保持這個狀態(超時時間:一般預設是60s)。由於網路中斷,或者對端很忙還沒來得及傳送FIN、或者對端有bug忘記關閉連線等都會導致主動端長時間處於FIN_WAIT2狀態。如果主動方發現大量FIN_WAIT2狀態時,應該引起相關人員的注意,這可能是網路不穩、對端程式bug的表現。 NOTE:這個狀態如果超時,將直接進入CLOSED狀態。關於超時時間你可能需要了解:tcp_fin_timeout這個配置引數。 2.3 TIME_WAIT 這個狀態最常見。主動方收到對端的FIN後進入TIME_WAIT狀態。然後傳送最後一個確認ACK到對端。之後等待2個最大的報文存活週期,正常的關閉流程客戶端TCP連線都會經過這個狀態,最終進入CLOSED狀態。所以我們使用netstat -anpt命令發現客戶端有很多的TIME_WAIT,一般這是正常的現象。 NOTE:
這個狀態的連線還沒有真正關閉,所以佔用的檔案控制代碼和埠號等資源也沒有釋放。如果TIME_WAIT狀態的連線過多,將會導致檔案控制代碼或者埠號等資源不足。如果你想控制這個狀態連線的數量,你可能需要詳細瞭解:tcp_max_tw_buckets tcp_tw_recycle tcp_tw_reuse三個系統配置。 對於有大量短連結服務的伺服器來說,服務端主動關閉連線會產生大量的TIME_WAIT,如果不及時回收這些個連線會造成資源嚴重浪費。不過一個應用層系統都有自己最大併發連線數限制、作業系統也有最大TIME_WAIT連線數限制。所以一般也不會產生大的問題。 * 等待2MSL的原因: (1)保證殘留網路報不會被新連線接收而產生資料錯亂。由於自己上一次傳送的資料包可能還殘留在網路中,等待2MSL時間可以保證所有殘留的網路報在自己關閉前都已經超時。 (2)確保自己最後ACK發到對端。因為ACK傳送也可能會失敗,這是對端會重新發送FIN,如果已經CLOSED了那麼對端將收到RST而不是ACK了,這不符合TCP可靠關閉策略。 2.4 CLOSING 雙發幾乎同時都呼叫了close介面主動關閉連線,此時都進入了FIN_WAIT1狀態。如果在FIN_WAIT1狀態期望收到對方的ACK但卻收到了對方的FIN,這時候雙方都進入CLOSING狀態。然後都給對方一個ACK確認,收到了ACK後就會進入CLOSED狀態了。 NOTE:這個狀態如果超時,將直接進入CLOSED狀態。關於這個超時時間的設定我暫時還沒有找到? 2.5 CLOSE_WAIT(重點說明下這個狀態) 這個狀態表明TCP連線等待被關閉。只可能在被動方出現。如果被動方存在大量的CLOSE_WAIT狀態需要因為我們的特別注意了。我們要仔細研究確認為什麼被動方遲遲不願關閉連線(或許是我們程式中的bug開啟了連線,用完後卻忘記關閉) 目前開發過程中遇到如下這個場景導致被動方有很多的CLOSE_WAIT狀態: A是一個應用程式,B是一個tomcat伺服器 A開了一個連線Conn,傳送請求給B A接受相應資料後沒有呼叫Conn.close關閉連線,在A端垃圾回收這些Conn物件前,這些連線一直保持著 B端的連線超時後會主動發起關閉連線請求給A,此時A進入了CLOSE_WAIT狀態,B進入了FIN_WAIT2狀態,由於A遲遲不傳送FIN給B,B端觸發timeout直接進入了CLOSED狀態。 這樣一個場景B端由於有超時設定一個為60s,不會存在大量的FIN_WAIT2狀態 但是A端就會殘留大量的CLOSE_WAIT狀態(CLOSE_WAIT狀態也有超時,但是太大,預設為43200s,詳情見tcp_timeout_close_wait系統配置)。還好A端的java虛擬機器的最大對記憶體配置較小,由於CLOSE_WAIT狀態連線同樣佔用了記憶體資源,數量很多後就會觸發垃圾回收,此時A端的CLOSE_WAIT的連線Conn物件就會被銷燬了(同時記憶體和控制代碼、埠等資源也被釋放了) 很明顯這是一個bug導致的問題,如果沒有及時回收的話,就會把記憶體、控制代碼或者埠等資源給用完,導致程式crash掉。 2.6 LAST_ACK 這個狀態只可能在被動端出現。當被動端呼叫close介面關閉連線後便會進入這個狀態,同時傳送一個FIN給對端。在接受對端的ACK確認後便會進入CLOSED狀態,這個狀態一般不易出現,除非網路中斷,一般對端會很快給與響應的。 2.7 狀態總結 主動端可能出現的狀態:FIN_WAIT1、FIN_WAIT2、CLOSING、TIME_WAIT 被動端可能出現的狀態:CLOSE_WAIT LAST_ACK 敘述中提到的超時時間在我的另一片文章tcp連線超時那點事中有具體的分析 NOTE: (1)主動端出現大量的FIN_WAIT1時需要注意網路是否暢通、出現大量的FIN_WAIT2需要仔細檢查程式為何遲遲收不到對端的FIN(可能是主動方或者被動方的bug)、出現大量的TIME_WAIT需要注意系統的併發量/socket控制代碼資源/記憶體使用/埠號資源等。 (2)被動端出現大量的 CLOSE_WAIT 需要仔細檢查為何自己遲遲不願呼叫close關閉連線(可能是bug,socket開啟用完沒有關閉)

相關推薦

tcp連線關閉注意事項

注:tcp關閉連線不區分客戶端和服務端,哪一埠可以主動發起關閉連線請求。所以為了描述方便,描述中的“主動方”表示主動發起關閉連線一方,“被動方”表示被動關閉連線一方。 1. tcp關閉連線狀態轉換   上圖是tcp連線主動關閉端的狀態轉換圖: (1)應用層呼叫close函式發起關閉連線請求 (2

React生命週期函式注意事項

React生命週期函式 生命週期函式是指在某一個週期自動執行的函式。 React中的生命週期執行過程 以下是React中的常用的生命週期函式,按個部分中按照自動執行順序列出,這幾個過程

1112_maven專案使用Druid連線池配置步驟注意事項[mysql資料庫]

maven專案使用Druid連線池配置步驟和注意事項[mysql資料庫] 2018年06月13日 17:09:25 個人分類: java 注:這兩天搭建專案時,使用Druid連線池入了不少坑;以此記錄; MySQL Server 5.7.21 + mysql-connector-j

TCP連線狀態及TIME_WAIT過多的解決方法

上圖對排除和定位網路或系統故障時大有幫助,但是怎樣牢牢地將這張圖刻在腦中呢?那麼你就一定要對這張圖的每一個狀態,及轉換的過程有深刻地認識,不能只停留在一知半解之中。下面對這張圖的11種狀態詳細解釋一下,以便加強記憶!不過在這之前,先回顧一下TCP建立連線的三次握手過程

Android中Service的使用注意點(LocalService)

開始,先稍稍講一點android中Service的概念和用途吧~ Service分為本地服務(LocalService)和遠端服務(RemoteService): 1、本地服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此

BottomSheet 的注意事項

android support library更新的比較快,使用了幾個控制元件挺不錯,不過今天只寫BottomSheet 。 OK,這個東西肯定很多人都沒聽過和用過,其實用起來特別方便和簡單,不過它的使用需要引入Behavior機制,別說你沒聽說過Behavi

TCP建立連線斷開連線過程

最近在看TCP這塊知識的時候對TCP連線三次握手斷開四次斷開不是很瞭解,找了下面一片文章講的很詳細,收藏下! 原文地址:http://blog.sina.com.cn/s/blog_60a4fcef0101e813.html TCP是一個面向連線的服務,面向連線的服務是電話系統服務模式的抽象

TCP通訊過程以及tcp連線連線

1. TCP連線 當網路通訊時採用TCP協議時,在真正的讀寫操作之前,server與client之間必須建立一個連線,當讀寫操作完成後,雙方不再需要這個連線 時它們可以釋放這個連線,連線的建立是需要三次握手的,而釋放則需要4次揮手,所以說每個連線的建立都是需要

mysql許可權使用注意事項及mysql 資料型別innodb,myisam區別

mysql使用者許可權管理(Grant,Revoke) MySQL可以為不同的使用者分配嚴格的、複雜的許可權。這些操作大多都可以用SQL 指令Grant(分配許可權)和Revoke(回收許可權)來實現。 Grant可以把指定的權 限分配給特定的使用者,如果這個使用者不存在

java的UDPTCP北京-賽車平臺出租源碼分析

ati 消息 byte ide 一段 pack catch 打包 println 1、需求分析北京-賽車平臺出租Q1446595067 最近在和硬件做網口的傳輸協議,一開始告訴我說用TCP的socket進行傳輸,我說沒問題,就寫了個socket的發送和接收方法。but過了沒

linux netstat tcp(全連線連線

功能介紹(參考 LINUX MAN命令 大家可以自己去看一下 這裡只是列出常用的部分說明) 顯示網路連線狀態(如:LISTEN、ESTABLISHED、TIME_WAIT),路由地址,應用使用協議(如:TCP、UDP),IP和埠使用情況等其他網路資訊。 常用引數 –rou

Python之TCP OSI七層模型

1.OSI七層模型和TCP/IP四層 基本模型: OSI七層模型 先有模型,後有協議,先有標準,後有實踐,TCP/IP反之 ARP協議,獲取主機的mac地址,全世界唯一 應用程式:QQ、微信,我們開發

linux netstat、tcp(全連線連線

參考 LINUX MAN命令 大家可以自己去看一下 這裡只是列出常用的部分說明 功能介紹 顯示網路連線狀態(如:LISTEN、ESTABLISHED、TIME_WAIT),路由地址,應用使用協議(如:TCP、UDP),IP和埠使用情況等其他網路

深入理解Oracle表(5):三大表連線方式之Hash Join的定義,原理,演算法,成本,模式點陣圖

 Hash Join只能用於相等連線,且只能在CBO優化器模式下。相對於nested loop join,hash join更適合處理大型結果集        Hash Join的執行計劃第1個是hash表(build table),第2個探查表(probe table),

TCP三次握手(建立連線)與四次揮手(釋放連線

上圖畫出了TCP的建立連線的過程。假定主機A執行的是TCP客戶程式,而B執行TCP服務程式。最初兩端的TCP程序都處於 CLOSED(關閉)狀態。圖中在主機下面的方框分別是TCP程序所處的狀態。請注意,A主動開啟連線,而B被動開啟連線。 B的TCP伺服器程

TCP連線關閉—closeshutdown

先從最右邊的分支說說關閉監聽socket的那些事。用於listen的監聽控制代碼也是使用close關閉,關閉這樣的控制代碼含義當然很不同,它本身並不對應著某個TCP連線,但是,附著在它之上的卻可能有半成品連線。什麼意思呢?之前說過TCP是雙工的,它的開啟需要三次握手,三次握手也就是3個步驟,其含義為:客戶端

TCP協議(含長連線連線

1. TCP連線 當網路通訊時採用TCP協議時,在真正的讀寫操作之前,server與client之間必須建立一個連線,當讀寫操作完成後,雙方不再需要這個連線時它們可以釋放這個連線,連線的建立是需要三次握手的,而釋放則需要4次握手,所以說每個連線的建立都是需要資源消耗和時間消耗的 經典的三次握手示意圖: 經

linux防火牆開啟關閉

以下兩種方法一、暫時開啟和關閉防火牆 1種 service方式檢視防火牆狀態: [[email protected] ~]# service iptables statusiptables:未執行防火牆。開啟防火牆(即時生效,重啟後失效):[[email 

SVN trunk(主線) branch(分支) tag(標記) 用法詳細操作步驟

trac load mar span 必須 最可 objc copy 右鍵 原文地址:http://blog.csdn.net/vbirdbest/article/details/51122637 使用場景: 假如你的項目(這裏指的是手機客戶端項目)的某個版本(例如1.0

Storm容錯機制Acker實戰案例

storm acker 失敗重發 可靠性Storm中有個特殊的Executor叫acker,他們負責跟蹤spout發出的每一個Tuple的Tuple樹。當acker發現一個Tuple樹已經處理完成了,它會告訴框架回調Spout的ack(),否則回調Spout的fail()。Acker的跟蹤算法是Storm的主