国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

TIME_WAIT、CLOSE_WAIT

2019-11-14 14:50:03
字體:
來源:轉載
供稿:網友

 內容提要

  • TCP連接釋放的過程
  • TIME_WAIT
    • 大量TiME_WAIT的后果
    • 解決方案
  • CLOSE_WAIT
    • 大量CLOSE_WAIT的后果
    • 解決方案

 

 

TCP 連接釋放的過程

 

 

圖中,A是主動關閉的一方,B是被動關閉的一方。

 從圖中可以看出,如果處于TIME_WAIT狀態,說明是主動關閉的。如果處于CLOSE_WAIT,說明是被動關閉的。

 

TIME_WAIT

         從圖上看出,TIME_WAIT狀態下,會有2個MSL(最大報文存活時間)的等待時間,之后才會處于CLOSED狀態,并釋放資源。

 

 

         為了保證A發送的最后一個ACk報文段能夠到達B,其實就是為了讓B真正的關閉,這樣才能夠保證連接的雙方都關閉。畢竟是全雙工的通信,總不能出現A到B的連接是關閉的,B到A的連接是打開的,這樣只能算是半關閉狀態。

MSL 的默認值是120s,也就是2分鐘,所以2MSL就是4分鐘。也就是說主動關閉的一方,會等待4分鐘才會釋放相關資源。

 

出現TIME_WAIT會帶來的后果

1) 如果客戶端出現了大量的TIME_WAIT,那么在這4分鐘之內,想要再使用該Socket綁定的端口,肯定會報BindException了。

2) 如果服務端出現了大量的TIME_WAIT,則服務的性能會下降,因為底層有大量的Sturct  Socket沒有釋放,占內存,在用戶量很大時,會很卡。

3) 服務端重啟時,ServerSocket綁定的端口可能會處于TIME_WAIT狀態,也是會出現BindException異常的。

 

TIME_WAIT解決方案

         從程序設計的角度講:

                 服務端最好不要(或者少)出現TIME_WAIT狀態,畢竟這個問題是不可避免的。也就是要把TIME_WAIT分散到客戶端,即讓客戶端主動關閉連接。

         從運維的角度來考慮講:

                 就需要對操作系統的配置做調整了:

net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊,默認為0,表示關閉;net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉;net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間,單位s

  

CLOSE_WAIT

         根據上面的TCP連接釋放過程中可以看出,如果一方出現了CLOSE_WAIT狀態,說明在連接被動關閉后,沒有發送FIN報文段到對方。

        

    

 

         默認情況下,操作系統設定的Keepalive時間是2小時。

 

大量CLOSE_WAIT會帶來的后果

         如果發生在客戶端,說明連接是被服務端關閉的。客戶端的這些端口在這CLOSE_WAIT狀態內,是不能夠使用了。如果要使用,應會報BindExcepion了。

         如果發生在服務端,說明是客戶端關閉的,服務端同樣會變的更慢了。出現這種情況就要在服務端找原因了。

 解決方案

         從程序設計角度講

             1) 在另一端出現關閉了連接后,出現CLOSE_WAIT的一端為什么沒有相應的執行關閉連接操作。

             2) 如果這種現象發生的客戶端,還要去查為什么服務端要關閉這些連接,服務端該不該關閉。

    

    

操作系統中 TCPIP協議棧的底層實現:
TCP 建立連接以后,雙方就是對等的。不論是哪一方,只要正常 close(socket_handle),那么 TCP 底層軟件都會向對端發送一個 FIN 包。 FIN 包到達對方機器之后,對方機器的 TCP 軟件會向應用層程序傳遞一個 EOF 字符,同時自動進入斷開連接流程(要來回協商幾次,但這些都是自動的、不可控的)。什么是 EOF 字符?它其實什么也不是,只是一個標記,上層應用程序如果這時讀 socket 句柄的話,就會讀到 EOF,也就是說,此時 socket 句柄看起來里面有數據,但是讀不出來,因此 select 返回可讀(非阻塞模式下)read 不會阻塞(阻塞模式下)但是 read 的返回值卻是 0。 如果此時不是讀操作而是寫操作,并且此時 socket 已經斷開連接,那么 write 函數會返回 -1 且置 errno 為 EPIPE(如果忽略了 SIGPIPE 信號的話)或者引發 SIGPIPE 信號(如果沒忽略的話)

    

          如果從代碼上去解決這種問題,就應該是執行Socket(或者SocketChannel)的close()方法。執行這個方法時,才會去發送FIN報文段。

  

READ:
NIO:
if(socketChannel.read()==-1){ socketChannel.close(); }BIO:InputStream input=socket.getInputStream();...if(inpout.read()==-1){input.close();socket.close();}

WRITE:
寫的過程出現異常,就可以關閉了

 

 

        從運維的角度講

tcp_keepalive_time :INTEGER默認值是7200(2小時)當keepalive打開的情況下,TCP發送keepalive消息的頻率。(由于目前網絡攻擊等因素,造成了利用這個進行的攻擊很頻繁,曾經也有cu的朋友提到過,說如果2邊建立了連接,然后不發送任何數據或者rst/fin消息,那么持續的時間是不是就是2小時,空連接攻擊? tcp_keepalive_time就是預防此情形的.我個人在做nat服務的時候的修改值為1800秒)tcp_keepalive_PRobes:INTEGER默認值是9TCP發送keepalive探測以確定該連接已經斷開的次數。(注意:保持連接僅在SO_KEEPALIVE套接字選項被打開是才發送.次數默認不需要修改,當然根據情形也可以適當地縮短此值.設置為5比較合適)tcp_keepalive_intvl:INTEGER默認值為75探測消息發送的頻率,乘以tcp_keepalive_probes就得到對于從開始探測以來沒有響應的連接殺除的時間。默認值為75秒,也就是沒有活動的連接將在大約11分鐘以后將被丟棄。(對于普通應用來說,這個值有一些偏大,可以根據需要改小.特別是web類服務器需要改小該值,15是個比較合適的值)

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乡城县| 西贡区| 柘城县| 广饶县| 夏河县| 沙坪坝区| 临清市| 墨江| 兴安县| 万州区| 康乐县| 乌兰县| 重庆市| 南溪县| 东平县| 云林县| 绍兴县| 莱芜市| 徐水县| 澳门| 垦利县| 怀远县| 区。| 临桂县| 老河口市| 明星| 东乡县| 宜都市| 嘉黎县| 银川市| 宜春市| 孙吴县| 太仆寺旗| 朔州市| 榕江县| 普定县| 循化| 汶川县| 巴彦淖尔市| 凤庆县| 南雄市|