TCP協議相關問題

2021-08-03 09:43:07 字數 3447 閱讀 1089

當多個連線請求同時到達server,會怎麼樣?

1.tcp存在乙個連線佇列,對於新的連線請求,該tcp監聽的埠的連線佇列中還有空間則tcp模組對syn進行確認並完成連線的建立,丟進連線佇列。應用層只在三次握手的第三個報文收到後才知道這個新連線。

2.對於新的連線請求,連線佇列中如果沒有空間,tcp將不理會收到的syn,也不傳送rst。

3.應用層指明佇列大小,積壓值。

tcp時延確認問題

tcp在處理互動資料流(即成塊資料流)時,採用了delayed ack機制以及nagle演算法來減少小分組數目

工作原理:tcp延時確認時間通常為幾百毫秒,如果在延遲時間內有報文段要傳送的話,ack附加到資料報文段一起傳送;如果沒有,那麼當延遲時間到時,就單獨傳送ack

傳送方的上限如何確定?

擁塞視窗和通告視窗的最小值作為傳送上限

min(rwnd, cwnd)

連線雙方同時關閉會怎樣?

關於建連線時syn超時。

如果server端接到了clien發的syn後回了syn-ack後client掉線了,server端沒有收到client回來的ack,那麼,這個連線處於乙個中間狀態,即沒成功,也沒失敗。於是,server端如果在一定時間內沒有收到的tcp會重發syn-ack。在linux下,預設重試次數為5次,重試的間隔時間從1s開始每次都翻售,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發出後還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,tcp才會把斷開這個連線。

time_wait的作用

1)time_wait確保有足夠的時間讓對端收到了ack,如果被動關閉的那方沒有收到ack,就會觸發被動端重發fin,一來一去正好2個msl。

2)有足夠的時間讓這個連線不會跟後面的連線混在一起(你要知道,有些自做主張的路由器會快取ip資料報,如果連線被重用了,那麼這些延遲收到的包就有可能會跟新連線混在一起)。

time_wait數量太多

只要搜一下,你就會發現,十有**的處理方式都是教你設定兩個引數,乙個叫tcp_tw_reuse,另乙個叫tcp_tw_recycle的引數,這兩個引數預設值都是被關閉的,後者recyle比前者resue更為激進,resue要溫柔一些。另外,如果使用tcp_tw_reuse,必需設定tcp_timestamps=1,否則無效。這裡,你一定要注意,開啟這兩個引數會有比較大的坑——可能會讓tcp連線出一些詭異的問題。

使用tcp_tw_reuse和tcp_tw_recycle來解決time_wait的問題是非常非常危險的,因為這兩個引數違反了tcp協議。

tcp的擁塞控制-慢啟動、擁塞避免,快速重傳、快速恢復

tcp的擁塞控制主要原理依賴於乙個擁塞視窗(cwnd)來控制,在之前我們還討論過tcp還有乙個對端通告的接收視窗(rwnd)用於流量控制。視窗值的大小就代表能夠傳送出去的但還沒有收到ack的最大資料報文段,顯然視窗越大那麼資料傳送的速度也就越快,但是也有越可能使得網路出現擁塞,如果視窗值為1,那麼就簡化為乙個停等協議,每傳送乙個資料,都要等到對方的確認才能傳送第二個資料報,顯然資料傳輸效率低下。tcp的擁塞控制演算法就是要在這兩者之間權衡,選取最好的cwnd值,從而使得網路吞吐量最大化且不產生擁塞。

慢啟動

最初的tcp在連線建立成功後會向網路中傳送大量的資料報,這樣很容易導致網路中路由器快取空間耗盡,從而發生擁塞。

因此有了慢啟動,當新建連線時,cwnd初始化為1個最大報文段(mss)大小,傳送端開始按照擁塞視窗大小傳送資料,每當有乙個報文段被確認,cwnd就增加1個mss大小

開始 —> cwnd = 1

經過1個rtt後 —> cwnd = 2*1 = 2

經過2個rtt後 —> cwnd = 2*2= 4

經過3個rtt後 —> cwnd = 4*2 = 8

擁塞避免

從慢啟動可以看到,cwnd可以很快的增長上來,從而最大程度利用網路頻寬資源,但是cwnd不能一直這樣無限增長下去,一定需要某個限制。tcp使用了乙個叫慢啟動門限(ssthresh)的變數,當cwnd超過該值後,慢啟動過程結束,進入擁塞避免階段。對於大多數tcp實現來說,ssthresh的值是65536(同樣以位元組計算)。擁塞避免的主要思想是加法增大,也就是cwnd的值不再指數級往上公升,開始加法增加。此時當視窗中所有的報文段都被確認時,cwnd的大小加1,cwnd的值就隨著rtt開始線性增加,這樣就可以避免增長過快導致網路擁塞,慢慢的增加調整到網路的最佳值。

上面討論的兩個機制都是沒有檢測到擁塞的情況下的行為,那麼當發現擁塞了cwnd又該怎樣去調整呢?

首先來看tcp是如何確定網路進入了擁塞狀態的,tcp認為網路擁塞的主要依據是它重傳了乙個報文段。

此時會進行下面操作:

1.把ssthresh降低為cwnd值的一半

2.把cwnd重新設定為1

3.重新進入慢啟動過程。

從整體上來講,tcp擁塞控制視窗變化的原則是aimd原則,即加法增大、乘法減小。

超時重傳機制

超時重傳指的是,傳送資料報在一定的時間週期內沒有收到相應的ack,等待一定的時間,超時之後就認為這個資料報丟失,就會重新傳送。這個等待時間被稱為rto.

比如,傳送端發了1,2,3,4,5一共五份資料,接收端收到了1,2,於是回ack 3,然後收到了4(注意此時3沒收到)

對此有兩種選擇:

一種是僅重傳timeout的包。也就是第3份資料。

另一種是重傳timeout後所有的資料,也就是第3,4,5這三份資料。

快速重傳

tcp在收到亂序到達包時就會立即傳送ack,tcp利用3個相同的ack來判定資料報的丟失,此時進行快速重傳,快速重傳做的事情有:

1.把ssthresh設定為cwnd的一半

2.把cwnd再設定為ssthresh的值(具體實現有些為ssthresh+3)

3.重新進入擁塞避免階段。

快速恢復

後來的「快速恢復」演算法是在上述的「快速重傳」演算法後新增的,當收到3個重複ack時,tcp最後進入的不是擁塞避免階段,而是快速恢復階段。具體如下:

1. cwnd = cwnd/2

sshthresh = cwnd

然後啟動快速恢復演算法:

設定cwnd = ssthresh+ack個數*mss(一般情況下會是3個dup ack)

如果只收到dup ack,那麼cwnd = cwnd + 1, 並且在允許的條件下傳送乙個報文段

如果收到新的ack, 設定cwnd = ssthresh, 進入擁塞避免階段

更多tcp相關

TCP協議的問題

server端接收到client端資訊後不會返回給client端 tcpechoserver.cpp 定義控制台應用程式的入口點。include stdafx.h include include include pragma comment lib,ws2 32.lib define grs all...

TCP網路協議問題

題目描述 在如今的網路中,tcp 是一種被廣泛使用的網路協議,它在傳輸層提供了可靠的通訊服務。眾所周知,網路是存在時延的,例如使用者先後向伺服器傳送了兩個指令 op1 和 op2,並且希望伺服器先處理指令 op1,再處理指令 op2 但由於網路時延,這兩個指令可能會失序到達,而導致伺服器先執行了指令...

http 協議相關問題

1 說一下什麼是http協議?對器客戶端和 伺服器端之間資料傳輸的格式規範,格式簡稱為 超文字傳輸協議 2 什麼是http協議無狀態協議?怎麼解決http協議無狀態協議?曾經去某創業公司問到 3 說一下http協議中302狀態 阿里經常問 4 http協議有什麼組成?請求報文包含三部分 響應報文包含...