TCP的三次握手與四次揮手

2021-08-20 04:01:08 字數 3935 閱讀 2267

1.tcp的許多特性都與tcp是面向連線的這個特性有關。每一條tcp連線有兩個端點,那麼tcp連線的端點是什麼呢?不是主機,不是主機ip,不是程序,也不是運輸層的協議埠,tcp連線的端點叫套接字,埠號拼接到ip位址即構成了套接字

2.傳輸連線有三個階段,包括連線建立資料傳送和連線釋放。

在tcp連線建立過程中要解決以下問題:

(1)要使每一方都能確認對方的存在

(2)要允許雙方協商一些引數(如最大視窗值,是否使用最大視窗擴**項和時間戳選項以及服務質量等)

(3)能夠對運輸實體資源(如快取大小,連線表中的專案)進行分配

主動發起連線建立的應用程序叫做客戶,而被動等待連線建立的應用程序叫做伺服器

3.tcp連線的建立過程(三次握手)

假定主機a執行的是tcp客戶程式,而b執行tcp伺服器程式,最初兩端的tcp程序都處於closed(關閉狀態),a主動開啟連線,b被動開啟連線

客戶端狀態的轉化:

[syn-sent->establish]:connect()呼叫成功 ,則進入establish狀態,開始讀寫資料

伺服器狀態轉化:

[syn-rcvd->establish]:服務端一旦收到客戶端的確認報文,就進入establiash ,就可以進行資料的讀寫了

在建立連線的過程中,客伺服器的程序分別先建立傳輸控制塊tcb,準備接受客戶程序的連線請求,然後伺服器程序就進入listen狀態,等待客戶端的連線請求。

tcp的客戶也建立乙個tcb,向b發出連線報文段,這時首部中的同步為syn=1(在建立連線時用來同步序號),同時選擇乙個初始序號seq=x,tcp 規定:syn報文段不能攜帶資料,但要消耗乙個序號,這時客戶端程序進入syn-sent(同步已傳送)狀態

伺服器收到連線請求報文後,如果同意建立連線,則向客戶傳送確認,在確認報文中應把syn位和ack位都置為1,確認號是ack=x+1,同時也為自己選擇乙個初始序號seq=y,這個報文段也不能攜帶資料,但同樣也要消耗掉乙個序號,這時伺服器程序進入syn-rcvd(同步收到)狀態。

tcp客戶收到伺服器的確認後,還要向伺服器給出確認,確認報文段的ack置1,確認號ack=y+1,而自己的序號seq=x+1,tcp標準規定,ack報文段可以攜帶資料,但如果不攜帶資料就不消耗序號。這時,tcp已經建立連線,客戶進入establish(已經建立連線)狀態

當伺服器收到客戶端的確認後,也進入establish狀態。

4.為什麼要進行三次握手

主要是為了防止已失效的報文段突然又傳送到伺服器,因而產生錯誤。

正常情況下,客戶發出連線請求,但因連線請求報文丟失而為收到確認,於是客戶再重傳一次連線請求,後來收到確認,建立連線,資料傳輸完後釋放連線,客戶一共傳送了兩個連線請求報文段,其中第乙個丟失,第二個傳送到伺服器端,沒有已失效的連線請求報文段

異常情況,客戶發出乙個連線請求報文段,並且沒有丟失,而是在某些網路節點長時間滯留了,以致延誤到連線釋放以後的某個時間才到達伺服器端,本來者是乙個早已失效的報文段,但伺服器收到這個已經失效的報文段之後,就誤認為是客戶端又傳送了一次新的連線請求,於是向客戶端發出確認報文段,同意建立連線。假定不採用三次握手,這是就確認新的連線建立了。由於客戶沒有發出建立連線的請求,因此不會理睬伺服器端的確認,但伺服器端卻認為新的連線已經建立了,並一致等待客戶端發來資料,伺服器的許多資源被白白浪費了;如果採用三次握手,客戶端不會向伺服器端的確認發出確認,伺服器端由於收不到確認,就知道客戶端並沒有要求連線建立。

4.tcp的連線釋放過程

資料傳輸結束後,通訊的雙方都可釋放連線,現在客戶端(a)和伺服器端(b)都處於establish狀態,a的應用程式先向其tcp發出連線釋放報文段,並停止再傳送資料,主動關閉tcp連線,a把釋放報文段首部的終止控制位fin置為1,其序號seq=u,它等於前面已經傳送過的資料的最後乙個位元組的序號加1,這時a進入fin-wait-1(終止等待1)狀態,等待b的確認,tcp規定:fin報文段即使不攜帶資料,它也消耗掉乙個序號

b收到a發來的釋放報文段後即發出確認,確認號是ack=u+1,假設這個報文段自己的序號是v,等於b前面已經傳送過的資料的最後乙個位元組的序號加1,然後b就進入close-wait(關閉等待)狀態,tcp伺服器程序這時應通知高層應用程序,因而從a到b這個方向的連線就釋放了,這時的tcp處於半關閉狀態,即a已經沒有資料要傳送了,但是若b要傳送資料,a仍要接收,b到a這個方向的連線並沒有關閉,這個狀態可能會持續一段時間。

a收到b的確認後,就進入fin-wait-2(終止等待2)狀態,等待b發出的連線釋放報文段。

如果b已經不需要向a傳送資料了,其應用程序就通知tcp釋放連線,這是b發出的連線釋放報文段將fin置為1,現假定b的序號為w(在半關閉狀態下,b可能又傳送了一些資料),b還必須重複上次已經傳送過的確認訊號,

ack=u+1,這時b就進入last-ack(最後確認)階段等待a的確認

a在收到b的連線釋放報文段後,必須對此發出確認,在確認報文中把ack置1,確認序號ack=w+1,而自己的序號seq=u+1,然後就進入time-wait(時間等待狀態),這時tcp連線並沒有是放掉。必須經過時間等待計時器設定的時間2msl後,a才進入到closed狀態。當a撤銷相應的傳輸控制塊tcb後,就結束了這次tcp連線。

5.為什麼a在time-waait狀態下必須等待2msl的時間呢?

(1)為了保證a傳送的最後乙個ack報文段能夠到達b。這個ack報文段有可能丟失,因而使處於last-ack狀態的b收不到對方傳送的fin-ack報文段的確認,b會超時重傳fin+ack報文段,而a就能在2msl時間內收到這個重傳的fin+ack 報文段,接著a重傳一次確認,重新啟動2msl計時器,最後a和b都進入closed狀態。如果a在time狀態下不等待一段時間,而是在傳送完ack報文段後立即釋放連線,就無法收到b重傳的fin+ack ,因而也不會再傳送一次確認報文段,這樣b就無法按步驟進入closed狀態。

(2)a傳送完最後乙個ack報文段後,在經過2msl後,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失,這樣就不會使下乙個新的連線中出現舊的連線請求報文段。b只要收到a發出的確認,就進入closed狀態。同樣,b在撤銷相應的傳銷控制塊tcb後,就結束了這次tcp連線,b結束tcp連線的時間要比a早一些。

除了時間等待計時器外,tcp還有乙個保活定時器,當客戶與伺服器主動建立連線後,客戶端主機突然出現故障,顯然伺服器端就收不到客戶端發來的資料,這就需要保活定時器,伺服器每收到一次客戶端的資料,就重新設定保活計時器,時間設定通常是兩小時。

tcp協議規定,最先發起斷開連線的一方需要等待2msl,2msl是指乙個報文生存的最大時間,msl的值centos7上預設是60s,可以通過

cat /proc/sys/net/ipv4/tcp_fin_timeout
檢視msl的值。

解決在taime_wait狀態下引起bind失敗的方法?

在伺服器的tcp連線沒有完全斷開之前,不允許重新監聽,但這在某些情況下是不要合理的。當伺服器要處理大量的客戶端的連線,這時候由伺服器主動關閉連線,就會產生大量的time_wait連線。由於我們的請求量很大,就可能導致time_wait的連線數很多,導致伺服器的埠不夠用,無法處理新的連線。這時,我們可以使用setsockopt()函式設定socket描述符的選項so_reuseaddr為1,表示允許建立埠號相同但ip位址不同的多個socket描述符。

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...