1. 程式人生 > >TCP/IP詳解--連線狀態變遷圖CLOSE_WAIT

TCP/IP詳解--連線狀態變遷圖CLOSE_WAIT

 終止一個連線要經過4次握手。這由TCP的半關閉(half-close)造成的。既然一個TCP連線是全雙工(即資料在兩個方向上能同時傳遞,可理解為兩個方向相反的獨立通道),因此每個方向必須單獨地進行關閉。這原則就是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向連線。當一端收到一個FIN核心讓read返回0通知應用層另一端已經終止了向本端的資料傳送。傳送FIN通常是應用層對socket進行關閉的結果。

例如:TCP客戶端傳送一個FIN,用來關閉從客戶到伺服器的資料傳送。


    半關閉對伺服器究竟有什麼影響呢?先看看下面的TCP狀態轉化圖

                                  tcp狀態裝換圖



首先對上面這個圖示進行解釋:

CLOSED:表示初始狀態。對服務端和C客戶端雙方都一樣。
        LISTEN:表示監聽狀態。服務端呼叫了listen函式,可以開始accept連線了。
        SYN_SENT:表示客戶端已經發送了SYN報文。當客戶端呼叫connect函式發起連線時,首先發SYN給服務端,然後自己進入SYN_SENT狀態,並等待服務端傳送ACK+SYN。
        SYN_RCVD:表示服務端收到客戶端傳送SYN報文。服務端收到這個報文後,進入SYN_RCVD狀態,然後傳送ACK+SYN給客戶端。
        ESTABLISHED:表示連線已經建立成功了。服務端傳送完ACK+SYN後進入該狀態,客戶端收到ACK後也進入該狀態。
        FIN_WAIT_1:表示主動關閉連線。無論哪方呼叫close函式傳送FIN報文都會進入這個這個狀態。
        FIN_WAIT_2:表示被動關閉方同意關閉連線。主動關閉連線方收到被動關閉方返回的ACK後,會進入該狀態。
        TIME_WAIT:表示收到對方的FIN報文併發送了ACK報文,就等2MSL後即可回到CLOSED狀態了。如果FIN_WAIT_1狀態下,收到對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。
        CLOSING:表示雙方同時關閉連線。如果雙方几乎同時呼叫close函式,那麼會出現雙方同時傳送FIN報文的情況,此時就會出現CLOSING狀態,表示雙方都在關閉連線。
        CLOSE_WAIT:表示被動關閉方等待關閉。當收到對方呼叫close函式傳送的FIN報文時,迴應對方ACK報文,此時進入CLOSE_WAIT狀態。
        LAST_ACK:表示被動關閉方傳送FIN報文後,等待對方的ACK報文狀態,當收到ACK後進入CLOSED狀態。

  

三次握手和四次握手所對應的上述狀態:


客戶端主動關閉時,發出FIN包,收到伺服器的ACK,客戶端停留在FIN_WAIT2狀態。而服務端收到FIN,發出ACK後,停留在COLSE_WAIT狀態。
    這個CLOSE_WAIT狀態非常討厭,它持續的時間非常長,伺服器端如果積攢大量的COLSE_WAIT狀態的socket,有可能將伺服器資源耗盡,進而無法提供服務
    那麼,伺服器上是怎麼產生大量的失去控制的COLSE_WAIT狀態的socket呢?我們來追蹤一下。
    一個很淺顯的原因是,伺服器沒有繼續
發FIN包給客戶端。
    伺服器為什麼不發FIN,可能是業務實現上的需要,現在不是傳送FIN的時機,因為伺服器還有資料要發往客戶端,傳送完了自然就要通過系統呼叫發FIN了,這個場景並不是上面我們提到的持續的

COLSE_WAIT狀態,這個在受控範圍之內。
    那麼究竟是什麼原因呢,咱們引入兩個系統呼叫close(sockfd)和shutdown(sockfd,how)接著往下分析。
    在這兒,需要明確的一個概念---- 一個程序開啟一個socket,然後此程序再派生子程序的時候,此socket的sockfd會被繼承。socket是系統級的物件,現在的結果是,此socket被兩個程序開啟,此socket的引用計數會變成2。

    繼續說上述兩個系統呼叫對socket的關閉情況。
    呼叫close(sockfd)時,核心檢查此fd對應的socket上的引用計數。如果引用計數大於1,那麼將這個引用計數減1,然後返回。如果引用計數等於1,那麼核心會真正通過發FIN來關閉TCP連線。
    呼叫shutdown(sockfd,SHUT_RDWR)時,核心不會檢查此fd對應的socket上的引用計數,直接通過發FIN來關閉TCP連線。

     現在應該真相大白了,可能是伺服器的實現有點問題,父程序打開了socket,然後用派生子程序來處理業務,父程序繼續對網路請求進行監聽,永遠不會終止。客戶端發FIN過來的時候,處理業務的子程序的read返回0,子程序發現對端已經關閉了,直接呼叫close()對本端進行關閉。實際上,僅僅使socket的引用計數減1,socket並沒關閉。從而導致系統中又多了一個CLOSE_WAIT的socket。。。

如何避免這樣的情況發生?
子程序的關閉處理應該是這樣的:
shutdown(sockfd,SHUT_RDWR);

close(sockfd);
這樣處理,伺服器的FIN會被髮出,socket進入LAST_ACK狀態,等待最後的ACK到來,就能進入初始狀態CLOSED。


補充一下shutdown()的函式說明

linux系統下使用shutdown系統呼叫來控制socket的關閉方式

int shutdown(intsockfd,int how);

引數how允許為shutdown操作選擇以下幾種方式:

SHUT_RD:關閉連線的讀端。也就是該套接字不再接受資料,任何當前在套接字接受緩衝區的資料將被丟棄。程序將不能對該套接字發出任何讀操作。對TCP套接字該呼叫之後接受到的任何資料將被確認然後被丟棄。

SHUT_WR:關閉連線的寫端。

SHUT_RDWR:相當於呼叫shutdown兩次:首先是以SHUT_RD,然後以SHUT_WR

注意:

在多程序中如果一個程序中shutdown(sfd, SHUT_RDWR)後其它的程序將無法進行通訊.如果一個程序close(sfd)將不會影響到其它程序.

相關推薦

TCP/IP--連線狀態變遷CLOSE_WAIT

 終止一個連線要經過4次握手。這由TCP的半關閉(half-close)造成的。既然一個TCP連線是全雙工(即資料在兩個方向上能同時傳遞,可理解為兩個方向相反的獨立通道),因此每個方向必須單獨地進行關閉。這原則就是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向

TCP/IP--連線狀態變遷CLOSE WAIT

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

TCP/IP--TIME_WAIT狀態

Socket中的TIME_WAIT狀態 在高併發短連線的server端,當server處理完client的請求後立刻closesocket此時會出現time_wait狀態然後如果client再併發2000個連線,此時部分連線就連線不上了,用linger強制關閉可以解決此問

TCP/IP--TCP連線中TIME WAIT狀態過多

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

TCP/IP--TCP連線中TIME_WAIT狀態過多

1、TIME_WAIT狀態主要出現在主動關閉連線的一方,當進入TIME_WAIT狀態需要等待2MSL(2個最大報文生存時間)時間後就會關閉連線,在window 下預設是4分鐘,在通過登錄檔來修改,在centos 7中是1分鐘,並且是無法修改的2、查詢了很多文章,很多都說/pr

TCP/IP--TCP/IP連線各個狀態轉換分析

一、Linux伺服器上11種網路連線狀態:       圖:TCP的狀態機 通常情況下,一個正常的TCP連線,都會有三個階段:1、TCP三次握手; 2、資料傳送; 3、TCP四次揮手 注:以下說明最好能結合”圖:TCP的狀態機”來理解。 SYN: (同步序列編號,Synchronize Sequence

TCP/IP--TIME WAIT狀態

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

TCP/IP--TCP中異常關閉連線的意義 異常關閉的情況

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

TCP/IP--TCP三次握手建立連線與四次握手終止連線

1.TCP連線的建立 (1)首先是伺服器初始化的過程,從CLOSED(關閉)狀態開始通過順序呼叫SOCKET、BIND、LISTEN和ACCEPT原語建立Socket套接字,進入LISTEN(監聽)狀態,等待客戶端的TCP傳輸連線請求。      (2)客戶端最開始也是從CLOSED狀態開始呼叫SOCKET

TCP/IP學習筆記(13)-- TCP連線的建立與終止

1.TCP連線的建立            設主機B執行一個伺服器程序,它先發出一個被動開啟命令,告訴它的TCP要準備接收客戶程序的連續請求,然後服務程序就處於聽的狀態。不斷檢測是否有客戶程序發起連續請求,如有,作出響應。設客戶程序執行在主機A中,他先向自己的TCP發出主動開啟的命令,表明要向某個IP地址

TCP/IP學習筆記(10)-TCP連線的建立與中止

TCP是一個面向連線的協議,所以在連線雙方傳送資料之前,都需要首先建立一條連線。這和前面講到的協議完全不同。前面講的所有協議都只是傳送資料而已,大多數都不關心傳送的資料是不是送到,UDP尤其明顯,從程式設計的角度來說,UDP程式設計也要簡單的多----UDP都不用考慮資料分片

TCP/IP》學習筆記-第17/18章 TCP:概述、連線建立與終止

1、概述 TCP提供一種面向連線的、可靠的位元組流服務。全雙工通訊。一個TCP連線由一個4元組唯一確定:本地 IP地址、本地埠號、遠端 IP地址和遠端埠號。 TCP將使用者資料打包構成報文段;它傳送資料後啟動一個定時器;另一端對收到的資料進行確認,對失序的資

TCP/IP學習筆記(3)IP協議ARP協議和RARP協議

out 處理機 傳輸 包含 發送 res 這也 進行 默認 把這三個協議放到一起學習是因為這三個協議處於同一層,ARP協議用來找到目標主機的Ethernet網卡Mac地址,IP則承載要發送的消息。數據鏈路層可以從ARP得到數據的傳送信息,而從IP得到要傳輸的數據信息。   

TCP/IP學習筆記(8)-DNS域名系統

dns 支持 設置 類型 hosts name 安裝 報文 定義 前面已經提到了訪問一臺機器要靠IP地址和MAC地址,其中,MAC地址可以通過ARP協議得到,所以這對用戶是透明的,但是IP地址就不行,無論如何用戶都需要用一個指定的IP來訪問一臺計算機,而IP地址又非常不好記

TCP/IP

限制 測量 新的 簡寫 tcp/ip協議 當前時間 設備 註意 ip首部 TCP/IP概述 Transmission Control Protocol/Internet Protocol的簡寫,中譯名為傳輸控制協議/因特網互聯協議,又名網絡通訊協議,是Internet最

TCP/IP學習筆記(1)-基本概念【轉】

網絡號 最大的 net 容易 學習 ip地址 其他 title 編寫 轉自:http://blog.csdn.net/goodboy1881/article/details/665041 為什麽會有TCP/IP協議 在世界上各地,各種各樣的電腦運行著各自不同的操作系統為大家

TCP/IP卷一02

image 時間 .cn 沖突 字節 stat 最大值 列表 邏輯 1. 鏈路層的目的:   1.1 為IP模塊發送IP數據報和接收IP數據報;   1.2 為ARP模塊發送ARP請求和接收ARP應答   1.3為RARP模塊發送RARP請求和接收RARP應答 2.以太網(

TCP/IP卷一03

nbsp 計算 可靠 目的 cti 錯誤 同時 路由選擇 重傳 1.IP協議:不可靠(unreliable):不能保證IP數據報能成功到達目的地      無連接(connectionless):IP並不維護任何關於後續數據報的狀態信息,每個數據報的處理是相互獨立的。IP

TCP/IP卷一06

端口號 unix系統 一份 diff 拷貝 重傳 廣播地址 三次 cmp 1.ICMP(Internet控制報文協議):用來傳送差錯報文以及其他需要註意的信息,ICMP報文通常被IP層或者更高層協議(TCP或者UDP)使用,一些ICMP報文把差錯報文返回給用戶進程。同時,I

TCP-IP卷2:實現》【PDF】下載

nbsp ipa 3.3 由器 3.5 方法 1.4 計算機 copy 《TCP-IP詳解卷2:實現》【PDF】下載鏈接: https://u253469.pipipan.com/fs/253469-230062539 內容簡介 《TCP/IP詳解·