看了下「三次握手」和「四次揮手」,本以為這就是tcp,但其實tcp遠不止這些。面對網路中紛繁複雜的情況,作為承諾傳輸可靠的tcp協議,需要解決很多問題。例如:
其中任何乙個步驟都蘊含著精妙的演算法,我們不需要知道其中演算法是如何寫的,只需要懂得解決的過程就可。
tcp(transmission control protocol 傳輸控制協議)是一種面向連線、可靠的、基於位元組流的傳輸層通訊協議。
我們需要知道tcp工作在osi模型中的第四層——transport層。當傳送端傳送資料時,從應用層發下來,每一層都會新增頭部資訊,進行封裝,而資料接受端得到資料後也會每一層都會解封裝。
在osi模型中,每一層對應的作用和協議如下:
tcp是乙個其中傳輸層的乙個協議,那這個協議是如何定義,資料格式又是什麼樣子的呢?接下來進行進一步的剖析。
單位為位元組(byte)
上面就是tcp協議的頭部格式,這張圖是非常重要,對於理解tcp協議有很重要的幫助,接下來就詳細說明一下各個字段
初始序列號(initial sequence number):
在三次握手的過程中,雙方通過syn
報文來交換彼此的isn
。isn並不是乙個固定的值,而是每4ms加1,溢位則回到0,這個演算法使得**isn變得很困難。因為ip埠號以及ip是很容易偽造的,當攻擊者猜測isn之後,直接偽造乙個rst後,就可以強制連線關閉。
確認號(acknowledgement number):
32位確認序列號包含傳送確認一端所期望收到的下乙個序列號。因此,確認序列號應當是上次收到的資料位元組序號加1。不過,只有當標誌位ack
標誌為1時確認號才能生效。
tcp標誌(tcp flags):
tcp首部有6個標誌位元,他們主要的意思如下:
window:
視窗大小,也就是有名的滑動視窗,用來進行流量控制。
檢驗和:
占用兩個位元組,防止傳輸過程中資料報有損壞。
可選項:
常見的可選項
上圖是tcp三次握手的的過程
為什麼三次握手有不同的解釋,這裡引用幾個解釋:
tcp是乙個可靠位元組流傳輸連線,我們需要在不可靠通道中傳輸,為了使得其可靠,三次通訊是理論的最小值
在google groups的toplanguage中看到一帖討論tcp「三次握手」覺得很有意思。貼主提出「tcp建立連線為什麼是三次握手?」的問題,在眾多回覆中,有一條回覆寫道:「這個問題的本質是, 通道不可靠, 但是通訊雙發需要就某個問題達成一致. 而要解決這個問題, 無論你在訊息中包含什麼資訊, 三次通訊是理論上的最小值. 所以三次握手不是tcp本身的要求, 而是為了滿足"在不可靠通道上可靠地傳輸資訊"這一需求所導致的. 請注意這裡的本質需求,通道不可靠, 資料傳輸要可靠. 三次達到了, 那後面你想接著握手也好, 發資料也好, 跟進行可靠資訊傳輸的需求就沒關係了. 因此,如果通道是可靠的, 即無論什麼時候發出訊息, 對方一定能收到, 或者你不關心是否要保證對方收到你的訊息, 那就能像udp那樣直接傳送訊息就可以了.」。這可視為對「三次握手」目的的另一種解答思路。在謝希仁的《計算機網路》中「為了防止已失效的連線請求報文段又重新傳送到伺服器端,因而產生錯誤」,主要是為了防止伺服器一直等待而浪費資源
「已失效的連線請求報文段」的產生在這樣一種情況下:client發出的第乙個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是乙個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的乙個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用「三次握手」,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。」至此,tcp四次分手正式分手成功。
因為在服務端在接收到
fin
,往往不會立即返回fin
,必須等到服務端所有的報文都傳送完畢,才能傳送fin
。因此先發乙個ack
表示已經收到了客戶端的fin
,延遲一段時間才發fin
。這就造成了四次揮手。如果是三次揮手會怎麼養?
也就是說服務端將
ack
和fin
傳送合併為一次揮手,這個時候如果伺服器端有很多資料正在傳送,就會造成延遲很長時間才能傳送fin
導致客戶端以為自己發的fin
沒有到達客戶端,從而讓客戶端不斷重發fin
三次握手之前,服務端的狀態從
closed
變為listen
,同時在內部建立了兩個佇列:半連線佇列和全連線佇列。也就是syn佇列和accept佇列第一次握手時,客戶端傳送
syn
到伺服器,伺服器收到回覆ack
和syn
,狀態由listen變為syn_rcvd,此時這個連線就被推入了syn佇列,也就是半連線佇列當客戶端返回ack,服務端接收時,三次握手完成。這個時候連線等待著被應用取走,在被取走之前,他會被推入tcp維護的佇列:全連線佇列
通俗大白話來理解tcp協議的三次握手和四次分手
tcp協議靈魂之問,鞏固你的網路底層基礎
tcp協議詳解
Tcp三次握手與四次揮手
tcp三次握手 四次揮手 在tcp ip協議中,tcp協議提供可靠的連線服務,採用三次握手建立乙個連線。第一次握手 建立連線時,客戶端傳送syn包 syn j 到伺服器,並進入syn send狀態,等待伺服器確認 syn 同步序列編號 synchronize sequence numbers 第二次...
TCP三次握手與四次揮手
也許三次握手你會經常聽到,但你知道三次握手的真正意義嗎,為什麼需要三次握手呢?首先我們必須明白tcp是面向連線的協議,無論哪乙個方向在傳送資料之前,都必須先在雙方之間建立連線。這一點與udp協議是不一樣的,udp在傳送資料報之前是不需要建立連線的。建立tcp連線的過程中,通訊的雙方需要互相發報文進行...
tcp三次握手與四次揮手
一.tcp三次握手 簡述 a傳送乙個請求給b,b發回確認,然後a再加以確認,來回共3次 1 第一次握手 客戶端傳送syn包 syn x 到伺服器,並進入syn send狀態,等待伺服器確認。2 第二次握手 伺服器收到syn包之後,必須確認客戶的syn ack x 1 同時自己也傳送乙個syn syn...