通過TCP/IP協議的學習,我們可以知道TCP協議是一種面向連接的、可靠的傳輸協議。其中,爲了保證客戶端與服務器連接的有效性,就有了本篇文章所要介紹的「三次揮手」;而「四次揮手」則是爲了保證連接的正確斷開。
首先,介紹一下TCP的幾個狀態:
建立TCP連接時會經過如下步驟:
被動打開
主動打開
,併發送SYN(syn = i)
包,告訴服務器發送數據的序列號SYN(syn = j)
,其中含有服務器發送數據的初始序列號。注:SYN
和ACK
是同時發送的,在一個數據包中ACK(ack = j+1)
數據包其中,因爲SYN需要佔據一個字節的序列號空間,因此ACK中確認號爲發來的SYN序列號加1;類似,FIN的ACK確認號爲該FIN序列號加1。
主動關閉
被動關閉
。進行確認(ACK, ack = i+1),在該進程接收的其他所有數據之後添加文件結束符(end-of-file)建立連接時,因爲發起連接的一端在發出請求後,連接建立之前,就不會再發出任何數據,因此接收連接請求的對端可以將ACK、SYN放在一個數據包裏發回給請求端,即需要三次數據發送。而斷開連接時,在一端主動斷開連接併發送FIN包後,對端接收到發來的FIN包,進行確認(ACK),然而此時服務器可能還在給另一端發送數據,只有在數據發送完後才能斷開連接,發送FIN包(所以不能像三次握手時那樣將ACK、SYN同時發送),另一端收到FIN後再進行確認併發送ACK,因此需要四次數據發送。
TCP建立的連接爲全雙工通道,可以雙向傳輸數據,因此在建立連接、斷開連接時,需要兩端都要進行請求與確認。
爲什麼建立連接的ACK、SYN可以同時發送,而斷開連接則需要分開發送?
建立、斷開連接都需要兩次請求與確認,只是建立連接時SYN、ACK可以同時發回,而在斷開連接時,由於被動關閉的一端可能還會發送數據,只有數據發完後才能發送ACK,所以只能分開發送,也就造成了建立連接爲三次,斷開連接反而成了四次。(建立連接時由於握手期間連接未完全建立,故不能發送其他數據)