這一層是面試的重點。在這里總結(jié)一下。
首先先看一下傳輸層位于哪一層。
TCP
可以看到傳輸層主要有UDP和TCP兩種協(xié)議。我們先來看一下較為復(fù)雜的TCP協(xié)議。TCP與UDP不同的是TCP是一個可靠數(shù)據(jù)傳輸協(xié)議。TCP中有幾個比較重要的機制:(1)超時與重傳機制 (2)流量控制機制 (3)擁塞控制機制。TCP包中的包頭也有相應(yīng)的字段用來實現(xiàn)相關(guān)字段。我們來看一下TCP包的包頭。

我們來說一下幾個字段存在的意義。
我們來說一下幾個字段存在的意義。
1. seq number和 ack number用于實現(xiàn)超時和重傳機制。同時擁塞控制也會用到。
2. receive window用于流量控制。
流量控制
流量控制存在的意義是使得發(fā)送方的發(fā)送速率和接收方的處理速率相匹配。避免出現(xiàn)發(fā)送方發(fā)送數(shù)據(jù)過快而接收方無法及時處理的問題。具體操作就是在接收方的ack包中帶上receive window字段保證發(fā)送端發(fā)送的速率不至于過快。
超時與重傳
在實現(xiàn)超時與重傳時,tcp使用了ack和seq號來做相關(guān)處理。我們先來了解一下這個seq和ack的使用方法。實際上seq是代表當(dāng)前包的序列號在發(fā)送端發(fā)送的時候帶上,ack是接收端收到的包的序列號(實際上TCP的ack是指定的收到的包的下一個即期望收到的包的序列號)在接收端收到的時候返回給發(fā)送端表明這個包我收到了。如果接收端發(fā)送的序列號和發(fā)送端期望收到的不一樣的話發(fā)送端就能知道發(fā)生了丟包。從而使用對應(yīng)的機制來重傳。超時重傳的機制主要有兩種:回退N幀和選擇重傳
回退N幀
回退N幀的本質(zhì)就是使用累計確認的方式即我發(fā)了12345 5個包只要我收到了第五個包的ack就表明我收到了5之前的所有包。但是如果發(fā)生了失序的包比如1245少了一個3失序的包全部丟棄返回收到ack2的信息。所以回退N幀的N就是這里來的,即發(fā)送方要重傳丟掉的包和之后的所有的包。看一個圖就清楚了。
選擇重傳
選擇重傳則是針對每一個包進行ack,如果某個包超時還沒有收到ack那么重傳對應(yīng)的包。對失序的包進行緩存。
TCP的重傳機制
TCP借鑒了gbn和selective repeat的優(yōu)點使用了帶累計確認的選擇重傳。即對失序的包進行存儲,同時返回累計確認的ack number。
擁塞控制
擁塞控制存在的意義是保證發(fā)送和接收方的速率不超過鏈路的承載量。避免出現(xiàn)使用速率過快,比如發(fā)送的數(shù)據(jù)包超過了鏈路承載的速率導(dǎo)致頻繁丟包。在實現(xiàn)擁塞控制時,tcp使用了ack和seq號來做相關(guān)處理。
其實主要就是分為3個階段:
1 慢啟動階段
cwnd設(shè)置為1個MSS,在這個階段cwnd(congestion window) 指數(shù)形式增長,直到出現(xiàn)超時或三次重復(fù)ack或者到達設(shè)定閾值。到達閾值切換為擁塞避免階段。超時進入慢啟動階段,三次重復(fù)ack進入快速恢復(fù)階段。
2 擁塞避免階段
在這個階段cwnd線性增長,直到出現(xiàn)超時或三次重復(fù)ack。超時進入慢啟動階段,三次重復(fù)ack進入快速恢復(fù)階段。
**3 快速恢復(fù)階段**
cwnd設(shè)置為三次重復(fù)ack前的一半(reno)還有一種是tahoe這種處理方式直接將狀態(tài)切換為慢啟動。然后切換為擁塞階段。如果超時切換為慢啟動階段。
著名的三次握手與四次揮手
tcp在建立連接的時候需要進行三次握手,在斷開連接的時候要進行四次揮手。
具體流程見圖
握手流程圖
首先要搞清楚為什么需要三次握手建立連接??戳撕芏嗖┛秃突卮穑覀€人總結(jié)的根本原因是兩個:同步雙方的信息和更新當(dāng)前的狀態(tài)。如果我們使用兩次握手會有什么問題呢?即A-> B發(fā)送SYN信息,B收到A的信息以后發(fā)送一個ACK回去就視為連接已經(jīng)建立。
1.? 資源的浪費
比如A->B發(fā)了一個SYN包。SYN超時后重傳一個新的SYN和新的隨機seq number。但是B收到舊的SYN包的時候會視為一個有效的請求并分配資源返回一個ACK給A。但是A已經(jīng)不會理會這個舊的ACK了只會用新的SYN建立的連接進行通信。B就會傻傻的等一個永遠不會發(fā)送信息的連接(屆不到的愛戀)。出現(xiàn)這個問題的原因就是狀態(tài)沒有更新。B不知道A的狀態(tài)已經(jīng)變化了。如果使用三次握手機制A在收到一個舊的ACK的時候就會發(fā)RST告訴B這個鏈接已經(jīng)不要了從而更新狀態(tài)。
2. 協(xié)商SEQ
在超時重傳機制里SEQ和ACK是實現(xiàn)機制的重要信息之一。通過三次握手可以同步雙方的信息A告訴B說要用這個seq,B->A B->A說好我使用這個seq。這樣就可以同步從A->B這個方向的seq。但是B->A也需要一組。但是在B->A這一步既可以確認A->B的seq也可以發(fā)送B->A的seq。因此本來應(yīng)該四步的操作可以簡化為3步。這樣就可以同步兩方的seq信息。
常見面試題
1.為什么要三次握手?
見上面的解析
2.SYN Seq Num的初始值是固定的嗎?
不是的。是由一個初始序列號( initial sequence number ISN)生成器生成的。這個生成器會用一個32位長的時鐘,差不多4μs增長一次,因此 ISN 會在大約 4.55 小時循環(huán)一次
(2^32位的計數(shù)器,需要2^32*4 μs才能自增完,除以1小時共有多少μs便可算出2^32*4 /(1*60*60*1000*1000)=4.772185884)
而一個段在網(wǎng)絡(luò)中并不會比最大分段壽命(Maximum Segment Lifetime (MSL) ,默認使用2分鐘)長,MSL 比4.55小時要短,所以我們可以認為 ISN 會是唯一的。
3. 為什么ISN要是隨機的值?
1. 防止舊的連接的包對新的連接產(chǎn)生影響。比如有一個舊的連接的數(shù)據(jù)包滯留在鏈路中,等到屬于他的連接關(guān)閉了才到目的地點。如果每次都是固定值,接收方可能將其視為當(dāng)前連接的數(shù)據(jù)包。
2. 安全考慮,由于是隨機的猜測將更加困難。如果攻擊者沒有辦法監(jiān)聽流量產(chǎn)生一個seq在接收窗口的數(shù)據(jù)包就十分困難。
4.什么是SYN攻擊
系統(tǒng)會維護一個半連接隊伍。即接收方已經(jīng)向發(fā)送方發(fā)送ack但是還沒有收到回復(fù)的隊列。攻擊者可以偽造IP短時間大量發(fā)送SYN請求,收到請求后不發(fā)ack。而服務(wù)端還需要維護這些資源從而達到dos攻擊的目的。
5. 為什么在前兩次握手不可以帶數(shù)據(jù)
主要是為了安全考慮,如果在前兩次就可以帶數(shù)據(jù)的話。服務(wù)器就需要分配資源存儲這些還沒有建立連接的對端發(fā)來的數(shù)據(jù)庫。如果惡意攻擊者發(fā)送大量SYN數(shù)據(jù)包就很容易成功實施dos攻擊。
揮手流程圖
這里可以看出來,在關(guān)閉連接的時候多了一次揮手流程。原因是在接收端收到FIN請求包的時候可能還在處理數(shù)據(jù),比如還有數(shù)據(jù)沒有發(fā)。因此并不能立刻關(guān)閉socket,只能發(fā)一個ACK包告訴請求發(fā)起端你的FIN請求我收到了。等到接收端處理完畢后才會發(fā)FIN。因此多了一次握手過程。這里有兩個比較重要的狀態(tài)一個是請求發(fā)起關(guān)閉連接端的TIME_WAIT的狀態(tài)和收到關(guān)閉連接端的CLOSE_WAIT狀態(tài)。
常見面試題
1 為什么要四次揮手?
見上文
2 為什么client要等 2個MSL再徹底關(guān)閉連接?
1. 為了防止最后一次揮手的ack包丟包,如果在TIMED_WAIT階段受到重復(fù)的FIN包則會重發(fā)最后一個ACK包。2. 防止當(dāng)前連接的數(shù)據(jù)包對下一個連接的影響,經(jīng)過兩根MSL可以認為鏈路中已經(jīng)沒有關(guān)于這個連接的數(shù)據(jù)包了。
3. server存在過多time-wait階段的連接怎么處理?
1. 可以修改linux編譯內(nèi)核選項允許CLOSE_WAIT狀態(tài)的端口重用 。2. 可以修改內(nèi)核選項允許加速回收。
UDP
和TCP相比UDP就簡單很多了。UDP是一個無連接的不保障可靠性的傳輸層協(xié)議。
UDP的包頭
從包頭可以看出UDP與TCP不同的是UDP多了一個length。UDP本質(zhì)是基于包的協(xié)議,而TCP是基于流的協(xié)議。因此TCP才會有著名的粘包問題。并且UDP是不包含源IP和目的IP的。因此在傳輸層UDP復(fù)用機制與TCP不同。UDP針對目的IP和目的端口號相同的請求會由一個進程處理,而TCP會由兩個來處理。
UDP的復(fù)用機制
TCP復(fù)用機制