TCP的三次握手和四次揮手

  • TCP協議介紹
    TCP(Transmission Control Protocol),是一個面向連接的協議,在運用次協議進行傳輸數據之前,都會進行三次握手的連接工作,當數據傳輸完畢
    ,雙方都會通知對方要釋放此連接(四次揮手)。
  • TCP標志位
    SYN表示建立連接,FIN表示關閉連接,ACK表示響應,PSH表示有 DATA數據傳輸,RST表示連接重置。其中,ACK是可能與SYN,FIN等同時使用的,比如SYN和ACK可能同時為1,它表示的就是建立連接之后的響應,如果只是單個的一個SYN,它表示的只是建立連接。TCP的幾次握手就是通過這樣的ACK表現出來的。但SYN與FIN是不會同時為1的,因為前者表示的是建立連接,而后者表示的是斷開連接。RST一般是在FIN之后才會出現為1的情況,表示的是連接重置。一般地,當出現FIN包或RST包時,我們便認為客戶端與服務器端斷開了連接;而當出現SYN和SYN+ACK包時,我們認為客戶端與服務器建立了一個連接。PSH為1的情況,一般只出現在 DATA內容不為0的包中,也就是說PSH為1表示的是有真正的TCP數據包內容被傳遞。TCP的連接建立和連接關閉,都是通過請求-響應的模式完成的。
  • 三次握手和四次揮手的圖解
Untitled 1.jpg
  • 三次握手過程
    主機A(client)和主機B(server)開始建立握手過程:
    第一次握手:主機A發送位碼為syn=1,隨機產生seq number=10001的數據包到服務器,主機B由SYN=1知道,A要求建立聯機,此時狀態為SYN_SENT;
    第二次握手:主機B收到請求后要確認聯機信息,向A發送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=20001的包,此時狀態由LISTEN變為SYN_RECV;
    第三次握手:主機A收到后檢查ack number是否正確,即第一次發送的seq number+1,以及位碼ack是否為1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到后確認seq值與ack=1則連接建立成功,雙方狀態ESTABLISHED。
    完成三次握手,主機A與主機B開始傳送數據。
    各狀態含義解釋
    CLOSED: 這個沒什么好說的了,表示初始狀態。
    LISTEN: 這個也是非常容易理解的一個狀態,表示服務器端的某個SOCKET處于監聽狀態,可以接受連接了。
    SYN_RECV: 這個狀態表示接受到了SYN報文,在正常情況下,這個狀態是服務器端的SOCKET在建立TCP連接時的三次握手會話過程中的一個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了一個客戶端測試程序,故意將三次TCP握手過程中最后一個ACK報文不予發送。因此這種狀態 時,當收到客戶端的ACK報文后,它會進入到ESTABLISHED狀態。
    SYN_SENT: 這個狀態與SYN_RECV遙相呼應,當客戶端SOCKET執行CONNECT連接時,它首先發送SYN報文,因此也隨即它會進入到了SYN_SENT狀 態,并等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。
    ESTABLISHED:這個容易理解了,表示連接已經建立了。
  • 四次揮手各狀態解釋
    TCP的連接的拆除需要發送四個包,因此稱為四次揮手(four-way handshake)。客戶端或服務器均可主動發起揮手動作。解析各種狀態含義:
    FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別 是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連接,向對方發送了FIN報文,此時該SOCKET即 進入到FIN_WAIT_1狀態。而當對方回應ACK報文后,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。
    FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時還有點數據需要傳送給你,稍后再關閉接。
    TIME_WAIT: 表示收到了對方的FIN報文,并發送出了ACK報文,就等2MSL后即可回到CLOSED可用狀態了。如果FIN_WAIT_1狀態下,收到了對方同時帶 FIN標志和ACK標志的報文時,可以直接進入TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。
    CLOSING: 這種狀態比較特殊,實際情況中應該是很少見,屬于一種比較罕見的例外狀態。正常情況下,當你發送FIN報文后,按理來說是應該先收到(或同時收到)對方的 ACK報文,再收到對方的FIN報文。但是CLOSING狀態表示你發送FIN報文后,并沒有收到對方的ACK報文,反而卻也收到了對方的FIN報文。什 么情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close一個SOCKET的話,那么就出現了雙方同時發送FIN報 文的情況,也即會出現CLOSING狀態,表示雙方都正在關閉SOCKET連接。
    CLOSE_WAIT: 這種狀態的含義其實是表示在等待關閉。怎么理解呢?當對方close一個SOCKET后發送FIN報文給自己,你系統毫無疑問地會回應一個ACK報文給對 方,此時則進入到CLOSE_WAIT狀態。接下來呢,實際上你真正需要考慮的事情是看你是否還有數據發送給對方,如果沒有的話,那么你也就可以 close這個SOCKET,發送FIN報文給對方,也即關閉連接。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連接。
    LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在發送FIN報文后,最后等待對方的ACK報文。當收到ACK報文后,也即可以進入到CLOSED可用狀態了。
  • 問題點
    整理網上知識點,有3個問題分析后得出的結論(不一定保證100%正確):
    1、 為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?
    這是因為服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求后,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一 個報文里來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未 必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之后,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這里的ACK報文 和FIN報文多數情況下都是分開發送的。
    2、 為什么TIME_WAIT狀態還需要等2MSL后才能返回到CLOSED狀態?
    因為雖然雙方都同意關閉連接了,而且握手的4個報文也都發送完畢,按理可以直接回到CLOSED 狀態(就好比從SYN_SENT 狀態到ESTABLISH 狀態那樣),但是我們必須假想網絡是不可靠的,你無法保證你(客戶端)最后發送的ACK報文一定會被對方收到,就是說對方處于LAST_ACK 狀態下的SOCKET可能會因為超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT 狀態的作用就是用來重發可能丟失的ACK報文。
    3、關閉TCP連接一定需要4次揮手嗎?
    不一定,4次揮手關閉TCP連接是最安全的做法。但在有些時候,我們不喜歡TIME_WAIT 狀態(如當MSL數值設置過大導致服務器端有太多TIME_WAIT狀態的TCP連接,減少這些條目數可以更快地關閉連接,為新連接釋放更多資源),這時我們可以通過設置SOCKET變量的SO_LINGER標志來避免SOCKET在close()之后進入TIME_WAIT狀態,這時將通過發送RST強制終止TCP連接(取代正常的TCP四次握手的終止方式)。但這并不是一個很好的主意,TIME_WAIT 對于我們來說往往是有利的
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容