無論是前端程式設計師還是後臺程式設計師,在面試中最常見的一個題目,便是為什麼TCP需要三次握手?
一個非常通俗地解釋便是,第一次握手是問對方能否聽到,第二次握手是對方發出的我聽到了,你是否聽得到,第三次握手則是再次迴應對方,我也聽到了。這個解釋雖然通俗易懂,但實際上並不是那麼的專業。
舉個簡單的例子,假如在第一次握手之後,沒有收到對方的迴應,這個時候又發起第二次請求,這個時候收到了對方的迴應。這個時候,這個相應是第一次的請求還是第二次的呢?
我們常說,TCP是可靠的連線,那麼,什麼是可靠的連線呢?在RFC793中,用於保證可靠性和流控制機制的資訊,包括 Socket、序列號以及視窗大小叫做連線。
Socket是傳送方與接收方的地址與埠號,視窗大小則是每次傳送的資料視窗大小,用來做流量控制,序列號則是每個資料包的序列號。我們都知道,TCP的可靠性,很大一部分就是對每個資料包的應答與超時重傳,用的正是這個序列號。
也就是說,TCP在三次握手的時候,就已經對這三個元素進行了確定。第一次握手的時候,傳送方發起一次SYN操作,告訴對方自己的序列號。第二次握手的時候,接收方會回覆一個ACK,同時也發起一次SYN操作,一個TCP包,同時包含了這兩個訊息。第三次握手的時候,傳送方回覆一個ACK,同時帶上應用資料,傳送給接收方。
這三次操作,缺一不可,少了任何一步,都不能保證雙方都能確認對方的Seq資訊正確。那麼,能不能多一次呢?
例如可以把第二次握手拆分兩步,分別傳送ACK與SYN。只是沒有必要,因為一個TCP包本身就能夠包含兩個訊息,多一次握手意味著更多的開銷。所以說TCP三次握手就可以,不需要四次。
回到最前面的問題,為什麼通俗的解釋不好,我認為,作為一個工程師,嚴謹是必須的,只有當你真正瞭解了TCP連線的真正目的,才能真正掌握技術的精髓。