1. 程式人生 > >為什麼要Time_wait

為什麼要Time_wait

Time_wait

啊,老哥們肯定會想,time_wait什麼鬼? 為毛我主動斷開tcp連線。發完最後一個ACK後不能直接斷開連線啊,我能做的都做了。但是…..
老鐵們你們想一下,ACK丟包是不會重傳的,但是FIN呢? 最後被動關閉的一直要是收不到ACK它會怎麼想,它肯定認為FIN包丟包了,那怎麼樣,重發唄。
重發之後呢,如果對端一直不會回覆ACK,那麼重傳一定次數後就會發送重置報文段然後斷開連線。那麼這些精彩的來了,現在網路上有這麼多FIN的重傳包,如果主動斷開連線的一方又重新立刻再次建立連線呢?直接血崩……
正傳資料就會發現一個FIN段,怎麼辦呢?一看序列號不是當前連線裡的序列號啊… 這怎麼辦只能傳送重置報文段了關閉連線。這豈不是又浪費資源,又得不償失影響下一次通訊嗎~~~~
所以主動斷開的最後一個ACK傳送完後,不能直接斷開連線,它必須確保對方收到最後一個ACK才能斷開連線,所以ACK過去一個MSL,如果ACK快到丟包這消耗了一個MSL,那麼對端會重傳FIN,這個FIN段又消耗了一個MSL,所以啊共2個MSL。所以time_wait時間倆個MSL。
所以說time_wait 就是為了防止在連線上有多個重傳的FIN包出現,所以必須time_wait這個是為了防止當再一次建立相同的新連線時防止收到老連線的資料包從而導致的影響。
不知道這波解釋為什麼time_wait,老哥們聽懂了沒有
對於為什麼3次握手?為毛不是2次/4次?
首先有個點是必須得知道的,tcp三次握手不止是為了建立連線,還要互相確認對方的當前的初始化序列號(這個序列號在Linux下是有雜湊演算法得來的),確保當前連線的安全性,如果不初始化,都是0開始的話,那麼連線將不安全。其次還要互相決定下來MSL的大小。
所以如果2次握手。client 發生了 SYN + 自己的初始化序列號,server收到了,這時候server將 syn+ack+自己序列號回覆給client , 如果這個包丟了,那麼client將不知道server的序列號。但是server自己並不知道 這個syn+ack丟包瞭如果2次的話,那麼client發現一直收到回覆就重傳了SYN段,那麼server收到後,會知道自己的包丟了,就會再次重發syn+ack。假設這個包 client接到了,現在通訊狀態是OK的。不過這個假設是建立在server發完後沒有立即傳送資料段的前提下。
但是如果 server發完資料段,它認為是連通的,並立即傳送一個數據,第一個syn+ack丟包了,client並不知道server的初始化序列號,突然收到了一個數據段,會發什麼? 很簡單,它誤以為是上一個同一連線的延遲包,傳送RST段,然後中斷連線,直接雪崩!!!!