tcp三次握手、四次揮手時序圖:
#tcp協議狀態機
1.tcp建立連線時的初始化序列號x、y可以是寫死固定的嗎?
如果初始化序列號(縮寫為isn:inital sequence number)可以固定,我們來看看會出現什麼問題。假設isn固定是1,client和server建立好一條tcp連線後,client連續給server發了10個包,這10個包不知怎麼被鏈路上的路由器快取了(路由器會毫無先兆地快取或者丟棄任何的資料報),這個時候碰巧client掛掉了,然後client用同樣的埠號重新連上server,client又連續給server發了幾個包,假設這個時候client的序列號變成了5。接著,之前被路由器快取的10個資料報全部被路由到server端了,server給client回覆確認號10,這個時候,client整個都不好了,這是什麼情況?我的序列號才到5,你怎麼給我的確認號是10了,整個都亂了。所以現在的方法是在乙個基準值得上產生乙個隨機值。
2.假如client傳送乙個syn包給server後就掛了或是不管了,這個時候這個連線處於什麼狀態呢?會超時嗎?為什麼呢?
client傳送syn包給server後掛了,server回給client的syn-ack一直沒收到client的ack確認,這個時候這個連線既沒建立起來,也不能算失敗。這就需要乙個超時時間讓server將這個連線斷開,否則這個連線就會一直占用server的syn連線佇列中的乙個位置,大量這樣的連線就會將server的syn連線佇列耗盡,讓正常的連線無法得到處理。目前,linux下缺省會進行5次重發syn-ack包,重試的間隔時間從1s開始,下次的重試間隔時間是前一次的雙倍,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發出後還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,tcp才會把斷開這個連線。由於,syn超時需要63秒,那麼就給攻擊者乙個攻擊伺服器的機會,攻擊者在短時間內傳送大量的syn包給server(俗稱 syn flood 攻擊),用於耗盡server的syn佇列。對於應對syn 過多的問題,linux提供了幾個tcp引數:tcp_syncookies、tcp_synack_retries、tcp_max_syn_backlog、tcp_abort_on_overflow 來調整應對。
3.client和server同時發起斷開連線的fin包會怎麼樣呢,tcp狀態是怎麼轉移的?
tcp的peer兩端同時發起fin包進行斷開連線,那麼兩端peer可能出現完全一樣的狀態轉移 fin_wait1——>closeing——->time_wait,也就會client和server最後同時進入time_wait狀態。
4.上圖中的四次揮手過程中,server端的ack確認包能不能和接下來的fin包合併成乙個包呢,這樣四次揮手就變成三次揮手了?
答案是可能的。
tcp是全雙工通訊,cliet在自己已經不會在有新的資料要傳送給server後,可以傳送fin訊號告知server,這邊已經終止client到對端server那邊的資料傳輸。但是,這個時候對端server可以繼續往client這邊傳送資料報。於是,兩端資料傳輸的終止在時序上是獨立並且可能會相隔比較長的時間,這個時候就必須最少需要2+2 = 4 次揮手來完全終止這個連線。但是,如果server在收到client的fin包後,在也沒資料需要傳送給client了,那麼對client的ack包和server自己的fin包就可以合併成為乙個包傳送過去,這樣四次揮手就可以變成三次了(似乎linux協議棧就是這樣實現的)。
5.四次揮手過程中,首先斷開連線的一端,在回覆最後乙個ack後,為什麼要進行time_wait呢(超時設定是 2*msl,rfc793定義了msl為2分鐘,linux設定成了30s),在time_wait的時候又不能釋放資源,白白讓資源占用那麼長時間,能不能省了time_wait呢,為什麼?
1)據tcp協議規範,不對ack進行ack,如果主動關閉方不進入time_wait,那麼主動關閉方在傳送完ack就走了的話,如果最後傳送的ack在路由過程中丟掉了,最後沒能到被動關閉方,這個時候被動關閉方沒收到自己fin的ack就不能關閉連線,接著被動關閉方會超時重發fin包,但是這個時候已經沒有對端會給該fin回ack,被動關閉方就無法正常關閉連線了,所以主動關閉方需要進入time_wait以便能夠重發丟掉的被動關閉方fin的ack。
2)防止鏈路上已經關閉的連線的殘餘資料報(a lost duplicate packet or a wandering duplicate packet) 干擾正常的資料報,造成資料流的不正常。這個問題和2)類似。
6.time_wait會帶來哪些問題呢?
time_wait帶來的問題注意是源於:乙個連線進入time_wait狀態後需要等待2*msl(一般是1到4分鐘)那麼長的時間才能斷開連線釋放連線占用的資源,會造成以下問題.
1) 作為伺服器,短時間內關閉了大量的client連線,就會造成伺服器上出現大量的time_wait連線,佔據大量的tuple,嚴重消耗著伺服器的資源。
2) 作為客戶端,短時間內大量的短連線,會大量消耗的client機器的埠,畢竟埠只有65535個,埠被耗盡了,後續就無法在發起新的連線了。
(由於上面兩個問題,作為客戶端需要連本機的乙個服務的時候,首選unix域套接字而不是tcp)
time_wait很令人頭疼,很多問題是由time_wait造成的,但是time_wait又不是多餘的不能簡單將time_wait去掉,那麼怎麼來解決或緩解time_wait問題呢?可以進行time_wait的快速**和重用來緩解time_wait的問題。有沒一些清掉time_wait的技巧呢?
time_wait快速**
同時開啟tcp_tw_recycle和tcp_timestamps(預設開啟)兩選項
time_wait重用
要同時開啟tcp_tw_reuse選項和tcp_timestamps 選項才可以開啟time_wait重用
深入理解TCP
tcp是面向連線的傳輸層層協議,可以為應用層提供可靠的資料傳輸服務。所謂的面向連線並不是真正意思上的連線,只不過是在傳送資料之前,首先得相互握手,也就是說接收方知道你要發資料給它了。而udp是面向無連線的傳輸層協議,並不提供可靠的資料傳輸。有乙個很恰當的比喻 udp傳輸就類似於寫信,接收方事先並不知...
詳解TCP協議
16位的源埠號 傳送源的埠號 16位的目標埠號 目標的埠號 32位的序號 互動的初始資料段,序號值由系統生成的隨機值 isn。後續的報文段的序號為isn 所攜帶資料在整個位元組流中的偏移量。特點 1 所有的報文段序號不重複。2 後續的報文段序號值比前面的大。32位的確認號 由接收段填充,其值為序列號...
TCP協議詳解
參考部落格 在可靠的tcp網路通訊中,客戶端和伺服器端通訊建立連線的過程可簡單表述為三次握手 建立連線的階段 和四次揮手 釋放連線階段 下圖是這兩個階段的乙個完整的表述 其狀態圖可以表示為,在tcp連線建立的時候,存在乙個如下的有限狀態機 在狀態轉化圖中,其中客戶端的狀態轉移用帶箭頭的粗實線表示,伺...