TCP IP協議 連線建立和終止

2021-07-12 02:57:25 字數 2735 閱讀 3628

tcp是乙個面向連線的協議,所以在連線雙方傳送資料之前,都需要首先建立一條連線。

client連線server:

當client端呼叫socket函式呼叫時,相當於client端產生了乙個處於closed狀態的套接字。

(1) 第一次握手:client端又呼叫connect函式呼叫,系統為client隨機分配乙個埠,連同傳入connect中的引數(server的ip和埠),這就形成了乙個連線四元組,客戶端傳送乙個帶syn標誌的tcp報文到伺服器。這是三次握手過程中的報文1。connect呼叫讓client端的socket處於syn_sent狀態,等待伺服器確認;syn:同步序列編號(synchronize sequence numbers)。

(2)第二次握手:伺服器收到syn包,必須確認客戶的syn(ack=j+1),同時自己也傳送乙個syn包(syn=k),即syn+ack包,此時伺服器進入syn_recv狀態;

(3) 第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1),此包傳送完畢,客戶器和客務器進入established狀態,完成三次握手。連線已經可以進行讀寫操作。

乙個完整的三次握手也就是: 請求—應答—再次確認。

tcp協議通過三個報文段完成連線的建立,這個過程稱為三次握手(three-way handshake),過程如下圖所示。

對應的函式介面:

由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

建立乙個連線需要三次握手,而終止乙個連線要經過四次握手,這是由tcp的半關閉(half-close)造成的,如圖:

(1)客戶端a傳送乙個fin,用來關閉客戶a到伺服器b的資料傳送(報文段4)。

(2)伺服器b收到這個fin,它發回乙個ack,確認序號為收到的序號加1(報文段5)。和syn一樣,乙個fin將占用乙個序號。

(3)伺服器b關閉與客戶端a的連線,傳送乙個fin給客戶端a(報文段6)。

(4)客戶端a發回ack報文確認,並將確認序號設定為收到序號加1(報文段7)。

對應函式介面如圖:

呼叫過程如下:

1) 當client想要關閉它與server之間的連線。client(某個應用程序)首先呼叫close主動關閉連線,這時tcp傳送乙個fin m;client端處於fin_wait1狀態。

2) 當server端接收到fin m之後,執行被動關閉。對這個fin進行確認,返回給client ack。當server端返回給client ack後,client處於fin_wait2狀態,server處於close_wait狀態。它的接收也作為檔案結束符傳遞給應用程序,因為fin的接收意味著應用程序在相應的連線上再也接收不到額外資料;

3) 一段時間之後,當server端檢測到client端的關閉操作(read返回為0)。接收到檔案結束符的server端呼叫close關閉它的socket。這導致server端的tcp也傳送乙個fin n;此時server的狀態為last_ack。

4) 當client收到來自server的fin後 。 client端的套接字處於time_wait狀態,它會向server端再傳送乙個ack確認,此時server端收到ack確認後,此套接字處於closed狀態。這樣每個方向上都有乙個fin和ack。

這是因為服務端的listen狀態下的socket當收到syn報文的建連請求後,它可以把ack和syn(ack起應答作用,而syn起同步作用)放在乙個報文裡來傳送。但關閉連線時,當收到對方的fin報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要傳送一些資料給對方之後,再傳送fin報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ack報文和fin報文多數情況下都是分開傳送的。

這是因為雖然雙方都同意關閉連線了,而且握手的4個報文也都協調和傳送完畢,按理可以直接回到closed狀態(就好比從syn_send狀態到establish狀態那樣):

一方面是可靠的實現tcp全雙工連線的終止,也就是當最後的ack丟失後,被動關閉端會重發fin,因此主動關閉端需要維持狀態資訊,以允許它重新傳送最終的ack。

另一方面,但是因為我們必須要假想網路是不可靠的,你無法保證你最後傳送的ack報文會一定被對方收到,因此對方處於last_ack狀態下的socket可能會因為超時未收到ack報文,而重發fin報文,所以這個time_wait狀態的作用就是用來重發可能丟失的ack報文。

tcp在2msl等待期間,定義這個連線(4元組)不能再使用,任何遲到的報文都會丟棄。設想如果沒有2msl的限制,恰好新到的連線正好滿足原先的4元組,這時候連線就可能接收到網路上的延遲報文就可能干擾最新建立的連線。

TCP IP協議詳解 二 建立和關閉連線

看了酷殼 上的 tcp 的那些事兒 系列文章,有一點很受啟發 鍛鍊一下自己是否使用較少的篇幅將tcp協議講解清楚。一般的同學寫博文,可能像攤大餅一樣,篇幅較多並且羅嗦。我以前寫文章時也是這個習慣,所以希望在以後的博文寫作過程中,盡量使用比較短的篇幅來講完想要講的內容。為了節約你的時間,本片文章主要講...

TCP 連線的建立和終止

1.伺服器通過呼叫socket,bind和listen三個函式準備接受外來連線,稱為被動開啟。2.客戶通過呼叫connect發起主動開啟,導致客戶tcp傳送乙個syn同步分節,告訴伺服器將在連線中傳送的資料的初始序列號。syn分節不包含資料,只包含乙個ip首部,乙個tcp首部及可能的tcp選項。3....

TCP連線建立和終止小結

如圖 1.請求端傳送乙個syn到伺服器的相應埠,以及初始序號isn 2.伺服器傳送包含伺服器的初始序號的syn作為應答,同時確認序號設定為客戶的isn 1 3.客戶將確認序號設定為伺服器的isn 1 最大報文段長度 mss 同時開啟 一般情況下,連線建立時是一方傳送syn,另一方傳送syn ack,...