關於網路連線CLOSE WAIT狀態的問題

2021-10-21 04:33:47 字數 2278 閱讀 1462

問題背景

在開發網路伺服器應用系統的時候,有時會碰到伺服器有大量的socket處於close_wait狀態,也無法關閉,導致伺服器無法接受新的使用者請求,最終導致伺服器奔潰,系統重啟才能解決。

為什麼會出現大量的close_wait狀態呢?

要解決這個問題,我們得先介紹一下socket斷開過程中的四次揮手。

終止tcp連線的四次揮手

由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。

假設終止命令由client端發起。

當clien端傳輸完成資料,或者需要斷開連線時:

client端傳送乙個fin報文給server端。(序號為m)

1.1. 表示要終止client到server這個方向的連線。

1.1. 通過呼叫close(socket) api。

1.3 表示client不再會傳送資料到server端。(但server還能繼續發給client端)

1.4 client狀態變為fin_wait_1

server端收到fin後,傳送乙個ack報文給client端。(序號為m+1)

2.1 server狀態變為close_wait

2.2 client收到序號為(m+1)的ack後狀態變為fin_wait_2

。。。server端也傳送乙個fin報文給client端。(序號為n)

3.1 表示server也要終止到client端這個方向的連線。

3.2. 通過呼叫close(socket) api。

3.3 server端狀態變為last_ack

client端收到報文fin後,也傳送乙個ack報文給伺服器。(序號n+1)

4.1 client狀態變為time_wait

server端收到序號為(n+1)的ack

5.1 server的狀態變為closed.

等帶2msl之後

6.1 client的狀態也變為close.

至此,乙個完整的tcp連線就關閉了。

兩個基本問題:

q: 我們看到close_wait出現在什麼時候呢?

a: 在sever端收到client的fin訊息之後。

q: 狀態close_wait在什麼時候轉換成下乙個狀態呢?

a: 在server端向client傳送fin訊息之後。

至此似乎明白了為什麼會出現close_wait的狀態:如果server端一直沒有向client端傳送fin訊息(呼叫close() api),那麼這個close_wait會一直存在下去。

原因分析

從上面我們看到出現close_wait,說明server端沒有發起close()操作,這基本上是使用者server端程式的問題了;通常情況下,server都是等待client訪問,如果client退出請求關閉連線,server端自覺close()對應的連線。

當然這也可能是業務實現上的需要,暫時不傳送fin,因為伺服器可能還有資料要發往客戶端,等傳送完所有應用資料最後再傳送fin訊息了;這個場景並不是這裡我們討論的大量colse_wait的問題了,因為這個還是可控的。

我們要討論的場景是什麼?我們先介紹兩個系統呼叫,前面也提到並且用到的close(socket)和shutdown(socket,how)接著往下分析。

我們知道乙個程序開啟乙個socket,然後此程序fork出子程序的時候,父程序已開啟的socket是會被繼承的,即子程序能夠繼續訪問這個socket。其結果就是,乙個socket被兩個程序開啟,乙個父程序和乙個子程序,此時socket的引用計數會變成2。

據此分析,很大可能性是使用者伺服器的程式實現有問題導致的大量close_wait的socket,比如父程序開啟了socket,然後通過fork出子程序來處理業務,父程序繼續對網路請求進行監聽,永遠不會終止;當客戶端發fin過來的時候,處理業務的子程序處理此fin訊息,呼叫close()對本端進行關閉,然而這個close()呼叫只是把socket的引用計數器減1,因為父程序還在執行,socket並沒關閉,這樣就導致系統中又多了乙個close_wait的socket,長此以往,就這樣了。

關於time_wait狀態

多說兩句關於time_wait的狀態,這個發生在client端,而且是不可避免的,其時間長度是固定的2msl,到期自動轉為closed,不會導致系統資源耗盡的問題。

msl是乙個系統級引數,可調。

GG 網路連線。

www.google.com 還有 maps.google.com 又不能訪問了。不太相信是 google 自身的技術原因。m 之類的競爭對手也不至於在新的瀏覽器裡採取什麼手段。真不知道怎麼揣測了。不知道是不是有 高能強智 的干擾項在起作用。這種技術在今天的這裡好像已經很成熟的樣子了。以前,還可以用...

virtualbox Ubuntu網路連線思路

1.首先ifconfig a檢視ubuntu的當前網路介面狀態 2.如果是網絡卡設定的問題,輸入以下命令修改網絡卡設定 新增網絡卡,設定動態ip 3.啟動網絡卡 sudo ifup eth0關閉命令是sudo ifdown eth0 4.重啟網路服務 sudo service network res...

共享網路連線

1.開啟無線網路連線 不管當前使用的是否無線網路 即不能禁用無線網路連線,否則需要設定共享的網路連線的 共享 選項卡不會出現。2.右鍵當前使用的網路連線 屬性 共享 勾上所有,並在中間的下拉框中選擇 microsoft virtual wifi miniport adapter 對應的網路連線。若看...