網路學習筆記(一):TCP連線的建立與關閉

白馬笑西風發表於2019-03-18

  五層網路模型分為:物理層、資料鏈路層、網路層、傳輸層、應用層。其中,傳輸層有兩種主要協議:面向連線的TCP(Transmission Control Protocol 傳輸控制協議)、無連線的UDP(User Datagram Protocol 使用者資料包協議)。
  TCP是面向連線的傳輸層協議,提供點對點的可靠交付服務。TCP是面向位元組流的,提供全雙工通訊,允許連線雙方任何時候都能傳送資料。

一、TCP資料段

  TCP傳送的資料單元是報文段,TCP報文段分為首部與資料兩部分,首部的各欄位能體現TCP的全部功能。TCP資料包被封在IP資料包裡。
  TCP資料段首部格式如下圖所示:

網路學習筆記(一):TCP連線的建立與關閉
  源埠目的埠各佔2個位元組。網路通訊的端點應該是主機中的程式而不是主機,通過網路層提供的IP地址和傳輸層提供的埠號能夠確定唯一的程式。
  序號佔4個位元組。TCP是以資料位元組流的形式傳輸資料的,位元組流中的每一個位元組都按順序進行編號。資料段首部中的序號是指要傳送資料位元組流中第一個位元組的序號。32位的序號可以對4GB的資料進行編號,一般編號是可以複用的,新序號傳送時,相同序號的舊資料早已到達終點。
  確認序號佔4個位元組。是指期望收到對方下一個報文段第一個資料位元組的序號。
  資料偏移佔4位。資料偏移是指資料段中的資料起始位置距離資料段的起始位置有多遠,簡而言之,就是資料段首部的長度。一般資料包的首部是20位元組,但是可以新增選項,導致首部的長度不確定。資料偏移的單位是32位,4位長度最大表示的數值是15,因此首部最大為60位元組。由此可知,首部中選項最大為40位元組。
  保留佔6位,當前應置為0。
  標誌位佔6位,用來說明報文段的性質。

1、URG:置為1時,表明緊急指標有效。
2、ACK:置為1時,表明確認序號有效。
3、PSH:置為1時,接收方應該儘快將報文段交給應用層。
4、RST:置為1時,表明重建連線。
5、SYN:建立連線時,用來同步序號。佔一個序號。
6、FIN:釋放一個連線。佔一個序號。

  視窗佔2個位元組。視窗是指傳送方表明自己能接收對方傳送的資料量。流量控制通過宣告視窗大小來完成。
  校驗和佔2個位元組,校驗的範圍包括首部和資料兩個部分。
  緊急指標佔2個位元組。只有當URG標誌位置為1時才有效。緊急指標是一個正的偏移量,與序號欄位一起確定緊急資料最後一個位元組的序號,該序號之後的資料就是普通資料。當視窗值為0時,依然可以傳送緊急資料。
  選項最長為40位元組,如果沒有選項,則報文段首部為20位元組。最初規定的只有一個選項:最大報文段長度 MSS,之後又陸續新增了視窗擴大選項、時間戳選項、選擇確認選項等。

二、建立連線

  TCP是面向連線的協議,在傳輸資料之前要先建立連線,在資料傳輸完畢之後要斷開連線。TCP連線的建立採取客戶伺服器方式,主動發起連線的應用程式叫客戶,被動等待建立連線的應用程式叫伺服器
  TCP連線的建立需要經過三次握手,即在客戶與伺服器之間交換三個TCP報文段。建立連線的過程如下圖所示:

網路學習筆記(一):TCP連線的建立與關閉
  最初客戶程式與伺服器程式都處於CLOSED(關閉)狀態,然後伺服器的TCP程式建立傳輸控制塊TCB,伺服器程式處於LISTEN(收聽)狀態。傳輸控制塊中儲存著連線中的一些重要資訊,比如:當前的傳送和接收序號、TCP連線表、指向傳送和接收快取的指標等。
  客戶程式發起連線之前建立傳輸控制塊TCB。建立連線時向伺服器傳送請求報文,傳送初始序號seq=x,同時將SYN標誌位置為1。根據TCP規定,SYN資料包不能攜帶資料,但是要消耗掉一個序號。此時,客戶程式處於SYN-SENT(同步已傳送)狀態。
  伺服器程式收到連線請求報文後,如果同意建立間接,則向客戶程式傳送確認報文。確認報文中的SYN與ACK標誌位都置為1。其中首部中的確認序號表示的是期望對方下一個報文段第一個資料位元組的序號,因為客戶程式傳送SYN報文消耗掉一個序號,因此確認報文首部中的確認序號應該是接收到的SYN報文中的序號加1,即ack=x+1。同時傳送自身的序號seq=y。此時,伺服器程式處於SYN-RCVD(同步收到)狀態。
  客戶程式收到確認報文後還要向伺服器程式傳送確認報文。ACK標誌位置為1,seq=x+1,ack=y+1。TCP標準規定,ACK報文段可以攜帶資料,但是不攜帶資料的話不消耗序號。此時,TCP連線已經建立,客戶程式處於ESTABLISHED(已建立連線)狀態。
  伺服器程式收到客戶程式的確認報文後進入ESTABLISHED(已建立連線)狀態。
  之所以需要客戶再次傳送確認報文,主要是為了防止失效的連線請求報文突然又傳送到伺服器程式。比如:使用者傳送請求報文A,因網路原因長期滯留了。超時之後使用者重新傳送請求報文B,順利建立連線。之後報文A到達伺服器程式,伺服器程式傳送確認報文,但是使用者認為並沒有傳送連線請求,因此不予理會。此時如果沒有第三次握手的機制,伺服器程式就會認為連線已經建立,並且一直等待客戶程式發來資料,白白浪費很多資源。

三、關閉連線

  資料傳輸完畢之後,通訊雙方都可以主動釋放連線。為行文方便,以客戶主動釋放連線為例。關閉連線過程如下圖所示:

網路學習筆記(一):TCP連線的建立與關閉

1、關閉連線四次握手過程

  客戶程式資料傳輸完畢後,發出釋放連線報文。序號seq=a,FIN標誌位置為1,TCP標準規定:FIN報文段即使不攜帶資料,也會消耗一個序號。此時客戶進入FIN-WAIT-1(終止等待1)狀態。
  伺服器程式收到釋放連線報文後,會發出確認報文。序號seq=b,確認序號ack=a+1,ACK標誌置為1。此時伺服器程式進入CLOSE-WAIT(關閉等待)狀態。整個TCP連線處於半關閉狀態,即客戶程式不能向伺服器程式傳送資料,但是能夠接收來自伺服器程式的資料。這個狀態可能會持續一段時間,直到伺服器程式資料傳送完畢,主動釋放連線。
  客戶程式收到伺服器的確認報文後,進入FIN-WAIT-2(終止等待2)狀態,等待伺服器程式傳送釋放連線報文。
  伺服器程式在資料傳輸完畢後,發出釋放連線報文。序號seq=c,確認序號ack=a+1,FIN和ACK標誌位都置為1。此時伺服器程式進入LAST-ACK(最後確認)狀態。
  客戶程式收到釋放連線報文後,發出確認報文。序號seq=a+1,確認序號c+1,ACK標誌位置為1。此時客戶程式進入TIME-WAIT(時間等待)狀態。經過時間等待計時器設定的時間2MSL後,客戶程式進入CLOSED狀態。
  伺服器程式收到確認報文關閉連線,因為主動發起關閉程式需要經過2MSL之後才會關閉,因此一般被動關閉程式的關閉時間要早一些。

2、MSL

  MSL叫做最長報文段壽命,RFC 793建議設定為2分鐘,但是TCP允許根據不同的情況來設定具體的時間。
  為什麼TIME-WAIT的程式需要在2MSL後進入CLOSED狀態呢?主要有以下兩個方面:
  第一,為了保證被動關閉程式能夠順利關閉連線。如果經過等待時間直接進入關閉狀態,不能夠保證被動關閉方是否收到確認關閉報文,一旦報文丟失,則被動關閉方無法正常關閉。關閉方有2MSL等待時間,在此期間,如果被動關閉程式沒有收到確認關閉報文,則會重傳釋放連線報文。收到重傳的釋放連線報文後,主動關閉方會重發確認報文,並重新啟動時間等待計時器,倒數計時2MSL後進入CLOSED狀態。
  第二,等待該連線中所有的報文從網路中消失。經過2MSL時間後,可以使連線傳送的報文從網路中消失,防止在下一個連線中出現舊的請求報文。

3、保活定時器

  保活定時器是一個有爭議的功能,保活並不在TCP的規範中,很多人認為保活功能不應該在TCP中實現,應該由應用程式來完成。
  保活計時器主要有三個缺點:

1、在出現短暫差錯時,一個很好的連線被釋放掉。
2、消耗多餘的頻寬。
3、在按分組計費的情況下會在網際網路上花掉更多的錢。

  保活功能主要是為伺服器應用程式提供的,保活定時器在兩端出現臨時故障時,能夠很恰當的把連線關閉。基於這種優點,TCP應用一般都實現了保活計時器。
  在客戶與伺服器建立連線後,如果客戶主機突然出現故障,這時保活計時器就發揮出作用了。伺服器每次收到使用者資料,都會重新設定保活定時器,時間通常是兩小時。若兩個小時沒有收到客戶的資料,伺服器會傳送一個探測報文段,隨後每隔75秒傳送一次。傳送10次之後仍無響應,伺服器認定客戶端發生故障,主動關閉這個連線。

四、總結

  傳輸層協議主要有兩種:TCP、UDP。TCP提供點到點的可靠交付服務,UDP不提供可靠交付。
  TCP資料包文段分兩部分:首部、資料。首部的欄位能體現出TCP的全部功能,首部最小20位元組,最大60位元組。
  TCP在傳輸資料前需要先建立連線,連線的建立需要經過三次握手。資料傳輸完畢後要關閉連線,連線雙方均可主動關閉連線,關閉連線需要經過四次握手。
  在連線的一方出現故障時,通過設定保活計時器能夠主動關閉連線,不至於使沒出現故障的一端陷入無意義的等待中。
如需轉載,煩請註明出處:www.cnblogs.com/lidengfeng/…

相關文章