傳輸層協議之TCP詳解

傳輸層協議概述

傳輸層的目標就是爲了向它的上一層(應用層)提供高效的、可靠的以及成本有效的數據傳輸服務,大多數時候,傳輸層也就是爲應用層的進程提供服務。傳輸層的信息傳輸,其實是端到端的傳輸,這裏的端指的是端口。

傳輸層有兩種服務,分別是面向連接的服務以及無連接服務,TCP協議屬於面向連接的服務,至於爲什麼TCP協議是面向連接的服務,接着看文章就能明白了。

傳輸層的工作過程可以用一個圖來表示(圖片來源於《計算機網絡第五版》):

圖片來源於《計算機網絡第五版》

TCP段結構

我們把TCP協議傳輸的信息叫做TCP段,TCP段由兩個部分組成:TCP段頭+數據(可選的)。爲什麼TCP段需要段頭呢?你想想,如果有一個人告訴你他到浦東機場了,想讓你去接機。除此之外,你不再有任何信息,那麼這個時候,你只有三個選擇:

一、 選擇不接機,他愛咋滴就咋滴。
二、 打電話問他,他在哪個航站樓,在哪個出口。
三、 自己去浦東機場一個一個出口的去找他在哪裏。

當然,如果你和他關係還算不錯,而且也不想麻煩的話,一定會選第二個方法吧。第二個方法所得到的出口信息就相當於TCP協議裏的端口,那麼這個端口是保存在哪裏的呢?沒錯,就是存在TCP段頭裏,當然,TCP段頭裏不止有端口號,還有很多其他的東西,接下來看看TCP段的格式吧(圖片來源於《計算機網絡第五版》):

圖片來源於《計算機網絡第五版》
圖中最上邊的小格子表示的一共是32位,可以看出,源端口以及目標端口都是16位,別的字段以此類推。接下來解釋一下每個字段的作用:

源端口:指的是消息發起方的端口號。
目標端口:指的是消息接收方的端口號。
序號:他的作用就和他的名字一樣明顯,是用來標識每個段的。如果要發送的數據太大,那麼序號的作用就很重要了,他可以用來標識每個TCP段的順序。
確認號:他的作用可以從字面意思來理解,不過,值得注意的是,確認號確認的不是已經收到的那個字節,確認的其實是希望接下來接收的字節,也就是說,他指的是下一個期待的字節。爲什麼會是這樣呢,因爲TCP採用的是累計確認,什麼是累計確認呢?在這之後再解釋吧。
TCP頭長度:這個字段表示的是頭部所佔的行數(一行32個bit),一定要記清楚,表示的是TCP段頭的行數。這個參數也是必要的,因爲TCP的頭長是可變的。
接下來的8個比特:這八個比特,我最關注的是ACK、SYN、FIN,這三個標誌位的作用就留在之後的TCP三次握手和TCP四次揮手來解釋了。
窗口大小:這個字段用向對方表明,自己還可以接收多大的數據。這個字段也是很重要的,爲什麼呢?你想,如果你們家已經住滿人了,那如果還有人去你們家借宿,你覺得你能接受嗎。詳細的介紹會在後邊的TCP的滑動窗口協議來講。
校驗和:用來保證數據在傳輸過程中的可靠性,如果數據損壞了,接收方算出來的校驗和就會發生變化了。
緊急指針:緊急指針和URG字段相關,具體的內容我也不在這裏講解了。

TCP建立連接

相信大家都聽到過很多類似“TCP三次握手”這樣的話吧,沒錯,TCP建立連接的過程就是要經過三次交互,具體過程請看圖:
a)正常情況下建立連接

主機1主機2SYN(SEQ=x)SYN(SEQ=y,ACK=x+1)(SEQ=x+1,ACK=y+1)主機1主機2

b)同時建立連接的情況

主機1主機2SYN(SEQ=x)SYN(SEQ=y)(SEQ=y,ACK=x+1)(SEQ=x,ACK=y+1)主機1主機2

TCP採用的是三次握手來建立連接的方式,接下來,我來詳細的講解一下建立連接的過程(在這裏,我把建立連接的發起方稱爲client,建立連接的接收方稱爲server):

1) clientserver發送TCP段,這個TCP段中,段頭的SYN字段會被置爲1,同時,他也會想server發送序列號x
2) server 在收到了client 發送的請求之後,也會向client發送TCP段來作爲迴應,這個段中,server 會把TCP段頭的ACK字段置爲1,並且此時server 段頭的確認號是x+1,再發送序列號爲y的報文 。
3) client 在收到server 的報文之後,也會向server發送一個TCP段,此時的TCP段頭的ACK字段被置爲1,TCP的序列號爲x+1,確認號爲y+1

在上邊,我給出的是正常建立連接的情況,當然,並不是每次建立連接都是這麼順利的,我們可能會面臨很多情況,例如:同時建立連接、TCP段丟失、SYN泛洪攻擊等。面對這些情況,TCP協議也有很多與之對應的策略,例如:超時重傳、SYN Cookie等。接下來詳細講一下吧。

TCP超時重傳

在使用TCP協議傳輸信息的時候,會面臨信息丟失的情況,那麼,交互雙方怎麼樣才能知道信息有沒有丟失呢?最常用的一個方法就是:當向對方發送一個數據的時候,開啓一個時鐘,通過時鐘來記錄過了多久這個數據包還沒有收到迴應,如果超過了一個規定的時間(這個時間一般是通過信息傳輸的最長時間(信息往返一次)來計算的),那麼就可以認定爲信息丟失了,此時再重傳丟失的信息。

SYN Cookie

這個方法留在以後的攻擊防護裏單獨講吧。

TCP連接釋放

TCP在釋放連接的時候,需要進行四次交互,也就是我們經常說的“四次揮手”,先看圖吧:

主機1主機2FIN(SEQ=x)ACK(SEQ=y,ACK=x+1)FIN(SEQ=y)ACK(SEQ=x+1,ACK=y+1)主機1主機2

具體過程是這樣的:

1) 想要斷開連接的一方a,會主動向另一方發送FIN置爲了1的TCP段,此時,就好比他告訴了另一方b,“我現在已經不會向你發送數據了,不過,你要發送數據的話,我還是可以接受的”。在發送了FIN段之後,a會把發送數據的通道關閉,但是接受數據的通道還是開啓的。
2) b在收到a的請求之後,也會向a發送一個ACK置爲了1的TCP段,就好比他在和他說,“好的,我知道了,不過我有些數據還沒有傳輸完畢,稍等一下”。
3) b在傳輸完數據以後,也會向a發送FIN被置爲了1的TCP段,來告訴a,他的信息已經傳輸完畢了,可以斷開連接了。
4) a在收到了b的FIN段之後,也會向b發送一個ACK字段,同時關閉與b的連接,b在收到這個段以後,也會關閉連接。

可現實往往不會對你這麼好,交互的每個環節都有可能會出問題,就拿兩軍對壘的問題來說吧,TCP連接釋放也會面臨這樣的問題,這個時候,設置一個計時器就很重要了。

TCP滑動窗口

還記得上文的TCP段頭的窗口大小字段的解釋被留下來了嗎,沒錯,TCP的滑動窗口協議就是和這個字段相關。說白了,其實滑動窗口就是指,在進行TCP交互的時候,TCP段頭的窗口大小是不斷變化的。爲什麼會需要這個協議呢?當發送方發送的數據太大,但是接收方已經沒地方再存放數據了,那麼,就會使得接收方被數據淹沒,接收方存放不了數據了,就只能選擇丟棄,這樣,會造成資源的浪費。但是有了窗口大小這個字段就不一樣了,接收方可以告訴發送方,接收方能夠接收的數據大小,發送方也能夠發送合適的數據量了。
我這小嘴叭叭的,這樣看着還是很沒意思吧,那就上個圖(圖片來源於《計算機網絡第五版》):

圖片來源於《計算機網絡第五版》

圖中的WIN指的是窗口大小。

TCP擁塞控制

在傳輸數據的時候,由於網絡並不是只有我們自己可以使用,所以會存在丟包現象,那麼,TCP是怎麼來控制這個現象的呢?

如果網絡中的數據包過多,超出了網絡的負載能力,這個時候,我們就可以稱之爲網絡擁塞了。TCP擁塞控制的核心在於他的擁塞算法。發送方在發送數據的時候,會設置一個慢啓動閥值。一開始的時候,擁塞窗口會被設置的比較大,例如64KB,但是在發生了超時重傳以後,慢啓動閥值會設置的比64KB小,例如32KB,這個時候,擁塞窗口的大小被設置爲1KB,如果每次都能到達一個新的確認,那麼,擁塞窗口的大小也會呈指數增長,當擁塞窗口的大小達到了慢啓動閥值以後,就會呈線性增長,這個時候,如果發生了超時,那麼,慢啓動閥值會設置的比32KB小,例如20KB,此時擁塞窗口的大小又是從1KB開始。

老樣子,還是看個圖吧(圖片來源於《計算機網絡第五版》):

圖片來源於《計算機網絡第五版》

TCP特點總結

我記得的不多,如果不全的話可以自己再搜一搜:
1) 全雙工
2) 面向連接的傳輸
3) 可靠的傳輸
4) 端到端的連接

書籍推薦

《計算機網絡第五版》
《TCP詳解卷Ⅰ》
《TCP詳解卷Ⅱ》

工具推薦

往後的幾篇文章再詳細的介紹一下吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章