客戶端和服務器在使用TCP連接傳輸數據的過程中,需要經過三次握手建立連接和四次握手斷開連接操作。
具體如下圖所示
上圖描述了TCP連接從建立到斷開的詳細過程,以下就其中的具體報文細節展開討論。
在TCP三次握手建立連接階段,客戶端首先向服務器發送一個SYN=1,Sequence=p的請求包。
如果服務器同意授予客戶端該鏈接,則發送ACK=p+1,SYN=1,Sequence=q的回應包。
最後在客戶端收到服務器的回應包以後,也會向服務器發送一個回應包,具體內容為ACK=q+1,SYN=0,Sequence=p+1。
對於TCP的斷開則需要四次握手,為什麼不是三次握手呢,具體原因為:
當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。
斷開連接的過程是由客戶端首先發起的,首先,客戶端會發送FIN=1,Sequence=m的斷開連接請求包。
服務器端收到請求以後,會發送一個確認包ACK=m+1,Sequence=n。
此時,客戶端到服務器端單方面的連接已經斷開了,客戶端不會再向服務器端發送數據包。而服務器還是可以向客戶端發送數據的,如果服務器端發送s個數據包以後不需要向客戶端發送數據了,此時可以向客戶端發送斷開連接請求。FIN=1,Sequence=m+s,ACK=m+1。
客戶端收到服務器的斷開請求以後,會發送一個確認包。Sequence=m+1,ACK=m+s+1;
注意,客戶端發送最後一次ACK包以後,還會等待2MSL(最大報文段生存時間),因為在網絡中包有可能會丟失,客戶端等待2MSL的時間是擔心服務器端沒有收到ACK包,從而重發FIN請求。