1. 程式人生 > >TCP 協議中的三次握手與四次揮手及相關知識點詳細介紹

TCP 協議中的三次握手與四次揮手及相關知識點詳細介紹

今天來聊聊面試頻率特別高的一個題目:TCP 協議中的三次握手與四次揮手。涉及到的知識點有:

1、TCP、UDP 協議的區別 2、TCP 頭部結構 3、三次握手與四次揮手過程詳解 4、什麼是 TIME_WATI 狀態

本文略長,需要有點耐心

一、TCP、UDP 協議的區別

在介紹這兩者的區別之前,我們要需要了解一個概念:TCP/IP 協議族。定義如下:

目前 Internet(因特網)使用的主流協議族是 TCP/IP 協議族,它是一個分層、多協議的通訊體系 《Linux高效能程式設計》

提取關鍵詞:分層、多協議和通訊。也就是說,它有多個層次,每個層次有不同的協議,這些層次之間通過協議相互協作,最終達到網路通訊的目的。

說到分層,應該不會很陌生,TCP/IP 協議族是一個四層協議系統,自底而上分別是:資料鏈接層、網路層、傳輸層、應用層。我們這裡要說到的 TCP 和 UDP 協議屬於傳輸層。(各層的作用及相關協議這裡暫時先不做介紹)

下面我們回到標題:TCP、UDP 協議的區別,總結起來這個問題的答案要點如下:

1、首頁它們倆都是傳輸層的協議,而所謂“傳輸層”,它是為兩臺主機提供端到端的通訊,即從 A <-> B 。

2、TCP 協議可靠,UDP 協議不可靠。可靠即指資料由 A 傳送到 B,是否能確保資料真的有送達到 B。TCP 協議使用 超時重傳、資料確認等方式來確保資料包被正確地傳送至目的端,而 UDP 協議無法保證資料從傳送端正確傳送到目的端,如果資料在傳輸過程中丟失、或者目的端通過資料檢驗發現數據錯誤,則 UDP 協議只是簡單地通知應用程式傳送失敗,對於 TCP 協議擁有的超時重傳、資料確認等需要應用程式自己來處理這些邏輯。

3、TCP 是面向連線的,UDP 是無連線的。這也比較好理解,因為 TCP 連線才需要“三次握手,四次揮手”。

4、TCP 服務是基於流的,而 UDP 是基於資料報的,基於流的資料沒有邊界(長度)限制,而基於資料報的服務,每個 UDP 資料報都有一個長度,接收端必須以該長度為最小單位將其所有內容一次性讀出。

5、當傳送方多次執行寫操作時,TCP 模組會先將這些資料放入 TCP 傳送緩衝區中,當 TCP 模組真正開始傳送資料時,傳送緩衝區中這些等待發送的資料可能被封裝成一個或多個 TCP 報文段發出,因此,TCP 模組發出的 TCP 報文段的個數與應用程式執行的寫操作次數是沒有固定數量關係的。同樣,當接收端收到一個或多個 TCP 報文段後,TCP 模組將這些資料按照序號(序號說明見下面 的 TCP 頭部結構)依次放入 TCP 接收緩衝區中,並通知應用程式讀取資料。接收端可選擇一次或者分多次將資料從緩衝區中讀出(這取決於使用者指定的應用程式讀緩衝區的大小)。因此,接收端讀取資料的次數與傳送端發出多少個報文段個數也沒有固定的數量關係

。總結來說,即**對於 TCP 連線,傳送端執行的寫操作次數與接收端執行的讀操作次數之間沒有任何資料關係,這也是基於流服務的特點。**而對於 UDP 服務,傳送端每執行一次寫操作,就會將其封裝成一個 UDP 資料報併發送之,同時接收端必須根據傳送的進行讀,否則就會丟包。因此,對於 UDP 連線,傳送端寫的次資料與讀的次數是一致的,這也是基於資料報的服務的特點

6、TCP 的連線是一對一的,所以如果是基於廣播或者多播的的應用程式不能使用 TCP,而 UDP 則非常適合廣播和多播。

總結一句定義:

TCP 協議(Transmission Control Protocal,傳輸控制協議)為應用層提供可靠的、面向連線的、基於流的服務。而 UDP 協議(User Datagram Protocal,使用者資料報協議)則與 TCP 協議完全相反,它為應用層提供不可靠、無連線和基於資料報的服務

二、TCP 頭部結構

TCP 報文結構分為頭部部分和資料部分,為什麼需要了解 TCP 頭部結構,因為在後面“三次握手與四次揮手”裡會用到頭部結構裡的標誌位。簡單瞭解下對理解後面的過程有一定的好處。

下面一一說明每個的作用: 16位源埠號與目的埠號,這個比較好理解,就不過多解釋。

32位序號:在建立連線(或者關閉)的過程,這個序號是用來做佔位,當 A 傳送連線請求到 B,這個時候會帶上一個序號(隨機值,稱為 ISN),而 B 確認連線後,會把這個序號 +1 返回,同時帶上自己的充號。當建立連線後,該序號為生成的隨機值 ISN 加上該段報文段所攜帶的資料的第一個位元組在整個位元組流中的偏移量。比如,某個 TCP 報文段傳送的資料是位元組流中的第 100 ~ 200 位元組,那該序號為 ISN + 100。所以總結起來說明建立連線(或者關閉)時,序號的作用是為了佔位,而連線後,是為了標記當前資料流的第一個位元組。

4位頭部長度:標識 TCP 頭部有多少個 32 bit 字,因為是 4位,即 TCP 頭部最大能表示 15,即最長是 60 位元組。即它是用來記錄頭部的最大長度。

6位標誌位,包括: URG 標誌:表示緊急指標是否有效。 ACK 標誌:確認標誌。通常稱攜帶 ACK 標誌的 TCP 報文段為確認報文段。 PSH 標誌:提示接收端應該程式應該立即從 TCP 接收緩衝區中讀走資料,為接收後續資料騰出空間(如果不讀走,資料就會一直在緩衝區內)。 RST 標誌:表示要求對方重新建立連線。通常稱攜帶 RST 標誌的 TCP 報文段為復位報文段SYN 標誌:表示請求建立一個連線。通常稱攜帶 SYN 標誌的 TCP 報文段稱為同步報文段FIN 標誌:關閉標誌,通常稱攜帶 FIN 標誌的 TCP 報文段為結束報文段。 <b>這些標誌位說明了當前請求的目的,即要幹什麼。</b>

16 位視窗大小:表示當前 TCP 接收緩衝區還能容納多少位元組的資料,這樣傳送方就可以控制傳送資料的速度,它是 TCP 流量控制的一個手段。

16 位校驗和:驗證資料是否損壞,通過 CRC 演算法檢驗。這個校驗不僅包括 TCP 頭部,也包括資料部分。

16 位緊急指標:正的偏移量,它和序號欄位的值相加表示最後一個緊急資料的下一位元組的序號。TCP 的緊急指標是傳送端向接收端傳送緊急資料的方法。

TCP 頭部選項:可變長的可選資訊,這部分最多包含 40 位元組,因為 TCP 頭部最長是 60 位元組,所以固定部分佔 20 位元組。這裡不做詳細介紹,可以參考《Linux高效能程式設計》3.2.2

三、三次握手與四次揮手過程詳解

先來解釋三次握手過程:

1、傳送端傳送連線請求,6位標誌為 SYN,同時帶上自己的序號(此時由於不傳輸資料,所以不表示位元組的偏移量,只是佔位),比如是 223。

2、接收端接到請求,表示同意連線,傳送同意響應,帶上 SYN + ACK 標誌位,同時將確認序號為 224(傳送端序號加1),並帶上自己的序號(此時同樣由於不傳輸資料,所以不表示位元組的偏移量,只是佔位),比如是 521。

3、傳送端接收到確認資訊,再發回給接收端,表示我已接受到你的確認資訊,此時標誌仍為 ACK,確認序號為 522。

涉及到的問題:為什麼是三次握手,而不是四次或者兩次?

首先解釋為什麼不是四次。四次的過程是這樣的:

傳送方:我要連你了。 接收方:好的。 接收方:我準備好了,你連吧。 傳送方:好的。

顯然接收方準備好連線並同意連線是可以合併的,這樣可以提高連線的效率。

再來,我們解釋為什麼不是兩次。其實也比較好理解,我們知道 TCP 是全雙工通訊的,同時也是可靠的,連線和關閉都是兩邊都要執行才算真正的完成,同時還需要確保兩端都已經執行了連線或者關閉。如果只有兩次,過程是這樣的:

傳送方:我要連你了。 接收方:好的。

很明顯,接收方並不知道也不能保證傳送方一定接收到 “好的” 這條資訊,一旦接收方真的沒有收到這條資訊,就會出現接收收“單方面連線”的情況,這個時候傳送方就會一直重試傳送連線請求,直到真正收到 “好的” 這條資訊之後才算連線完成。而對於三次,如果傳送方沒有等待到你回覆確認,它是不會真正處於連線狀態的,它會重試確認請求。

接著我們來看看四次揮手過程:

1、傳送方傳送關閉請求,標誌位為:FIN,同時也會帶上自己的序號(此時同樣由於不傳輸資料,所以不表示位元組的偏移量,只是佔位)。

2、接收方接到請求後,回覆確認:ACK,同時確認序號為請求序號加1。

3、接收方也決定關閉連線,傳送關閉通知,標誌位為 FIN,同時還會帶上第2步中的確認資訊,即 ACK,以及確認序號和自己的序號。

4、傳送方回覆確認資訊:ACK,接收方序號加1。

<b>涉及到的問題:</b>為什麼需要四次握手,不是三次?

三次的過程是這樣的:

傳送方:我不再給你傳送資料了。 接收方:好的,我也不給你發了。 傳送方:好的,拜拜。

這是因為當接收方收到關閉請求後,它能立馬響應的就是確認關閉,它這裡確認的是接收方的關閉,即傳送方不再發資料給接收方了,但他還是可以接收接收方發給他的資料。而接收方是否需要關閉“傳送資料給傳送方”這條通道,取決於作業系統。作業系統也有可能 sleep 個幾秒再關閉,如果合併成三次,就可能造成接收方不能及時收到確認請求,可能造成超時重試等情況。因此需要四次。

四、什麼是 TIME_WAIT 狀態

首先,我們來看一段程式碼(說了這麼多理論,終於要看點程式碼了)。這裡舉一個 python 簡單的使用 socket 進行 tcp 通訊的示例:

服務端:

socket_server_test.py

# -*- coding: utf-8 -*-
"""
@Time    : 2019/6/26 下午4:58
@Author  : Demon
@File    : socket_server_test.py
@Desc    : 
"""

import socket

HOST = '127.0.0.1'  # 標準的迴環地址 (localhost)
PORT = 9999        # 監聽的埠 (非系統級的埠: 大於 1023)


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 第三個引數,如果為0,也不可複用
# 第三個如果為1,可以複用
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
    print('Connected by', addr)
    while True:
        data = conn.recv(1024)
        print("data:", data)
        if data:
            print("close")
            s.close()
            break
        conn.sendall(data)

客戶端:

# -*- coding: utf-8 -*-
"""
@Time    : 2019/6/26 下午4:55
@Author  : yrr
@File    : socket_client_test.py
@Desc    : 測試 self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""

import socket

HOST = '127.0.0.1'  # 伺服器的主機名或者 IP 地址
PORT = 9999        # 伺服器使用的埠

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)

print('Received', repr(data))

執行效果:

我們會發現,當我們服務端主動關閉時,如果我們再次執行這個程式,會報錯誤說埠仍然被佔用。這就很奇怪了,明明已經關閉了連線,為什麼還會佔用著埠呢?我們使用 netstat -an|grep 9999 命令檢視,發現當前這個連線處於 TIME_WAIT 狀態。

我們來說下 TIME_WAIT 狀態。即當一方斷開連線後,它並沒有直接進入 CLOSED 狀態,而是轉移到 TIME_WAIT 狀態,在這個狀態,需要等待 2MSL(Maximum Segment Life,報文段最大生存時間)的時間,才能完全關閉。

涉及問題: 1、為什麼需要有 TIME_WAIT 狀態存在?

簡單來說有兩點原因如下:

a. 當最後傳送方發出確認資訊後,仍然不能保證接收方能收到資訊,萬一沒收到,那接收方就會重試,而此時傳送方已經真正關閉了,就接受不到請求了。

b. 如果傳送方在發出確認資訊後就關閉了,在接收方接到確認資訊的過程中,傳送方是有可能再次發出連線請求的,那這個時候就亂套了。剛連線完,又收到確認關閉的資訊。

2、為什麼時長是 2MSL 呢? 這個其實也比較好理解,所以我傳送確認資訊,到達最長時間是 MSL,而你如果沒接受到,再重試,時間最長也是 MSL,那我等 2MSL,如果還沒收到請求,證明你真的已經正常收到了。

正因為我們有這個 TIME_WAIT 狀態,所以通常我們說是客戶端先關閉,一般不會讓伺服器端先關閉。那如何避免出現關閉後端口被佔用的情況(即上面程式碼示例問題怎麼解決)呢?很簡單,加一行程式碼即可實現:

# socket.SO_REUSEADDR 表示 close 後端口可複用
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

相關推薦

TCP 協議握手揮手相關知識點詳細介紹

今天來聊聊面試頻率特別高的一個題目:TCP 協議中的三次握手與四次揮手。涉及到的知識點有: 1、TCP、UDP 協議的區別 2、T

TCP協議握手揮手

前言: TCP的連線與釋放過程: 首先就是客戶端主動發起連線、傳送請求,然後伺服器端響應請求,最後客戶端主動關閉連線。兩條豎線表示的是通訊的兩端(client與server),從上到下表示的是時

tcp協議報文和握手揮手

tcp報文 三次握手與四次揮手 tcp11種狀態tcp協議:tcp是面向連接、可靠的進程到進程之間的協議。tcp提供全雙工服務:即:數據可在同一時間雙向傳輸。tcp報文段首部格式:各字段含義:源端口號:16位字段,為發送端進程對應的端口號目標端口:16位字段,為接收端進程對應的端口號,接收方接收到數據

TCP協議握手揮手通俗解析

再次 方式 32位 sent 時間 應用層 系統 socket編程 檢測 TCP/IP協議三次握手與四次握手流程解析 一、TCP報文格式 TCP/IP協議的詳細信息參看《TCP/IP協議詳解》三卷本。下面是TCP報文格式圖: 圖1 TCP報文格式 上圖中

TCP協議握手揮手

文章目錄 TCP報文格式 三次握手 四次揮手 注 TCP報文格式 TCP/IP協議的詳細資訊參看《TCP/IP協議詳解》三卷本。下面是TCP報文格式圖: 上圖中有幾個欄位需要重點介紹下: (1

深入淺出之 TCP協議握手揮手、超時重發、流量控制、擁塞控制、UDP區別)

TCP/IP 中有兩個具有代表性的傳輸層協議,分別是TCP、UDP。TCP提供可靠的通訊傳輸,而UDP則常被用於讓廣播和細節控制交給應用的通訊傳輸。 要知道TCP為了這簡單描述“可靠的通訊傳輸”背後所做的努力,你會深感佩服其強大性。TCP的特徵:序列化+確認應

簡述TCP協議的六個標誌位和握手揮手的過程原理

簡述TCP協議的三次握手與四次揮手的過程及原理        今天,我們來分享一下TCP協議的六個標誌位和三次握手與四次揮手的過程及原理。        先介紹一下TCP中的六個控制位,      

TCP/IP協議握手握手流程

(1)第一次握手:Client將標誌位SYN設定為1,隨機產生一個值seq=x,並將該資料包傳送給Server,Client進入SYN_SENT狀態,等待Server確認。(2)第二次握手:Server收到資料包後由標誌位SYN=1知道Client請求建立連線,Server將標誌位SYN和ACK都置為1,ac

[計算機網路協議分析]TCP/IP協議握手握手流程解析

TCP/IP協議三次握手與四次握手流程解析 一、TCP報文格式 TCP/IP協議的詳細資訊參看《TCP/IP協議詳解》三卷本。下面是TCP報文格式圖: 圖1 TCP報文格式 上圖中有幾個欄位需要重點介紹下: (1)序號:Seq序號,佔3

【極客思考】計算機網路:Wireshark抓包分析TCP握手揮手

【摘要】本文重點分析計算機網路中TCP協議中的握手和揮手的過程。 【前提說明】 前段時間突然看到了一篇關於TCP/IP模型的文章,心想這段時間在家裡也用wireshark抓了點包,那麼想著想著就覺得需要複習一下網路知識,於是就有這篇博文的誕生。當然網上關於TCP相關的知識點也是芸芸,閒著無事也可以多googl

簡析TCP握手分手

丟包 現在 流量 tcp連接 首部 都是 字節序 鏈接 暫時 具體的關於TCP是什麽,我不打算詳細的說了;當你看到這篇文章時,我想你也知道TCP的概念了,想要更深入的了解TCP的工作,我們就繼續。它只是一個超級麻煩的協議,而它又是互聯網的基礎,也是每個程序員必備的基本功。首

TCP握手分手

int 有效 tcp三次握手 osi height -1 rcv time 就會 三次握手 解釋:客戶端A和服務器B剛開始處於CLOSED狀態,兩者之間沒有任何聯系,A主動打開,B被動打開由 CLOSED進入LISTEN狀態,這是A發送一個SYN=1的標

TCP握手揮手詳解

socket 抓包 掉線 syn 還要 就是 創建 iss closed TCP三次握手與四次揮手詳解 @(TCP/IP) [TOC] 1.TCP報文格式 TCP(Transmission Control Protocol) 傳輸控制協議。TCP是主機對主機層的傳輸控制協議

理解TCP/IP握手揮手的正確姿勢

ron eight AI 主動 ddos攻擊 ID set 什麽 方案 背景 和女朋友異地戀一年多,為了保持感情我提議每天晚上視頻聊天一次。 從好上開始,到現在,一年多也算堅持下來了。 問題 有時候聊天的過程中,我的網絡或者她的網絡可能會不好,視頻就會卡住,聽不到對方的聲音

以女朋友為例講解 TCP/IP 握手揮手

seq 關於 轉載 向上 情況 日常 socket 標示 但是 背景 和女朋友異地戀一年多,為了保持感情我提議每天晚上視頻聊天一次。 從好上開始,到現在,一年多也算堅持下來了。 問題 有時候聊天的過程中,我的網絡或者她的網絡可能會不好,視頻就會卡住,聽不到對方的聲音

TCP握手揮手過程

結束 傳輸 tro img 連接 回復 重新 選擇 主動斷開 TCP連接的建立(三次握手) 首先,客戶端與服務器均處於未連接狀態,並且是客戶端主動向服務器請求建立連接:   客戶端將報文段中的SYN=1(同步位),並選擇一個seq=x,(即該請求報文的序號為x) 將這

TCP握手揮手

number 雙工 地址 ffffff ber 通信 control ext des TCP的三次握手與四次揮手 一、TCP(Transmission Control Protocol 傳輸控制協議) TCP是面向對連接,可靠的進程到進程通信的協議

TCP鏈接的握手斷開

浪費 seq 建立連接時 tab 背景條 客戶端 設計 received 上帝 一直總覺得三次握手和四次斷開,之前老師講的有問題,經過自己再次琢磨,發現是的,老師講的沒毛病,這次也把自己的理解總結一下,讓對這個知識模糊的小夥伴再換種思路去理解 首先看一下TCP三次握手發生了

簡單理解TCP握手揮手

lar syn sdn -a art seq 而是 time_wait 揮手 seq(消息序號):第一次請求時,隨機生成一個值,而後每次+1 ack(確認序號):接收上一條信息的seq+1 SYN:發起一個新連接的請求時,為1 FIN:釋放一個連接的請求時,為1 ACK:與

抓包查看TCP/IP 的握手分手

請求報文 無聊 技術分享 表示 新的 回復 握手 字段 inf 閑的無聊,自己折騰了個三次握手與四次分手,不正確的地方請大家批評 10.0.0.1 主機A10.0.0.200 主機B 1)由主機A向B發送建立TCP連接的請求報文,請求報文中SYN字段設置為1,表示需要建立