1. 程式人生 > >為什麽TCP要3次握手?4次揮手?

為什麽TCP要3次握手?4次揮手?

應用 neu art ack nco linux 客戶 丟了 大量

為什麽要3次握手?假設存在以下過程:

A->B (寫信,我想和你吃飯)
B->A (寫信,收到,我也想和你吃飯)
A->B (寫信,收到)

其實呢,最開始兩步,是因為通信的雙方要互相通知對方自己的初始化的Sequence Number(縮寫為ISN:Inital Sequence Number)——所以叫SYN。

引申的問題有以下三個:

1、為什麽不是四次握手?”收到,我也想和你吃飯“為什麽不分成2次信發送?
  答案:這個是為了節省網絡的傳輸,類似tcp的延遲確認原理一樣~~~~

2、為什麽不是兩次握手?
  答案:那麽,如果B給A寫的 "收到,我也想和你吃飯" 信半路在路上丟了,那麽可能造成A不知道B願不願意陪A吃飯。這時候A會認為B還沒回答,一直在等回答B回答。。。。
     在計算機中,表現為B給A發的數據包全部都被A丟棄了,因為A認為鏈接還沒建立成功。而B看到給A發的數據包一直沒有回應,那麽B不斷重試,不斷給A發。。。。。

3、如果在B->A(寫信,收到,我也想和你吃飯)之後,A就斷線了。那麽B怎麽呢?
  答案:B每隔一段時間就給A重新發短信~~默認重發5次,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s。共等待1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s後,然後斷開念頭。
 
問題3,又可以這樣問,建連接時,如果SYN超時,那麽會怎麽樣?
  答案:在計算機中表現如果客戶端發完SYN後就馬上斷線,那麽服務器將會等待63秒,重發5次SYN-ACK,如果仍然無果,那麽TCP才會把斷開這個連接。

4、世界總是充滿了惡意,假設存在大量的類似A這樣的人,不斷給B (寫信,我想和你吃飯)。。。。那麽B肯定得累死,這就是大名鼎鼎的SYN洪水攻擊。
  解決:因此linux給了個參數tcp_syncookies來專門處理這種情況。這種情況原理是這樣的,A不會再苦苦等B 63秒,而是給B發一個特殊的暗號(Cookie)。然後B如果收到了還是想建立連接,那麽就使用這個特別的暗號Cookie來建立連接即可。【當SYN隊列滿了後,,,】
  解決方案存在的問題:這種情況【千萬不能應用於正常的大負載的連接的情況】,因為可能服務器給客戶端發的Cookie客戶端會真的沒收到。。。。這時候就gg了。參數可供你選擇,

  第一個是:tcp_synack_retries 可以用他來減少重試次數;
  第二個是:tcp_max_syn_backlog,可以增大SYN連接數;
  第三個是:tcp_abort_on_overflow 處理不過來幹脆就直接拒絕連接了
  
參考

https://blog.csdn.net/cws1214/article/details/52430554


為什麽要4次揮手?
理論上完全可以做到3次揮手。Server完全可以同時發送FIN和ACK,即將一般情況下的步驟2和步驟3合並!這就是延遲確認優化,在RFC793 3.5節!
而存在則合理,為什麽TCP搞成了4次揮手呢?是因為Server在收到Client的FIN報文後會立即ACK,然後再通知應用層來決定Server端到Client端的單向連接是否要關閉,如果應用層沒數據要發則Server此時再發一個FIN,這就導致比TCP建立多了一步,因為FIN和ACK不是在同一報文中發送。

為什麽TCP要3次握手?4次揮手?