一.確認應答/(確認)序列號
接收方接收到數據后,向發送方返回一個確認信號(ack),告訴發送方數據被成功接收。ACK報文段只是作為確認使用的,一般來說不攜帶應用層數據(載荷),也就是說只有報頭部分。但有可能和其他的數據進行合并,這個是后話
另外,TCP將每個字節的數據都進行了編號,叫做序列號,保證數據到達接收方時不會混亂
其次,每個ACK報文也有一個確認序列號,例如ACK(1001),其一是告訴發送方1000之前的數據我以及收到了;其二是讓發送方從1001開始發送
問題:當后發的數據(1001~2000)先到達服務器時,ACK是否會返回ACK(2001)?
其實服務器不會返回ACK(2001),因為數據(1~1000)還沒到達,也就是說ACK(1001)
都還沒返回給客戶端,憑什么返回ACK(2001)。
那么此時又引出一個問題,既然ACK(1001)沒返回,客戶端為什么可以發送數據(1001 ~2000)?
這是因為TCP協議發送數據時,不是一條一條發送的,這個到后面講滑動窗口時再細講
二.超時重傳
之前便說過,TCP雖然號稱可靠傳輸,但實際上數據不可能100%傳輸到對端,這光靠代碼是無法解決的
遇到上述情況時,會觸發TCP的超時重傳機制
發送方等待一段時間后,沒有收到服務器返回的ACK,那么就會默認該數據丟包了,會再次發送該數據,如果依然沒有收到ACK,會再次重發,但每次重發的時間間隔會拉長,達到一定次數后就不再重重發。
如果數據成功達到了,但是ACK丟包了,怎么辦?
雖然客戶端會重發數據,但是服務器緩沖區會對接收的數據進行檢查,相同序列號的數據不會接收的
三.連接管理/狀態轉換
3.1三次握手
(1)SYN:客戶端發起連接請求
(2)ACK:服務器表示你的請求我收到了,但到底要不要連接,ACK無法決定;SYN:服務器決定與服務器建立連接(一般來說服務器不會拒絕連接請求,除非服務器繁忙,所以ACK和SYN一般是同步返回給客戶端的)
(3)ACK:客戶端告訴服務器,你的ACK+SYN我也收到了
這就是三次揮手建立連接的過程
問題:兩次揮手能不能建立連接?四次揮手又那不能?
答案:兩次不行,四次多余。
我舉例說明,此時張三和李四開黑,因為不在同一個地方,所以要開麥交流,那么在開黑之前需要確定雙方的麥克風和聽筒都沒問題
至于四次握手沒必要我上面以及已經說過了,服務器的ACK和SYN是可以合并發送的,能一次發送就不兩次
3.2三次握手的狀態轉換
1.服務器和客戶端都沒啟動
2.服務器啟動,客戶端為啟動
3.服務器和客戶端都啟動
3.3四次揮手&狀態轉換
(1)FIN:客戶端調用close(也可能是服務器)并發送斷連請求
(2)ACK:服務器收到FIN后返回ACK告訴客戶端:我收到了你的斷連請求,并進入CLOSE_WAIT狀態
(3)FIN:服務器進入CLOSE_WAIT狀態后需要處理完之前的數據,再調用close并向客戶端發送FIN確認斷連。然后進入LAST_ACK狀態,等待客戶端發送最后的ACK
(4)ACK:客戶端收到FIN后進入TIME_WAIT狀態,同時發送ACK
當服務器收到ACK之后,就進入CLOSED狀態徹底關閉連接;
而客戶端會等待一段時間后才進入CLOSED狀態,為了確保服務器收到ACK
問題:服務器的ACK和FIN能不能合并?
答案是:不能,因為ACK和FIN發送的時間大概率不同步,服務器需要處理完之前的數據才能發送FIN;如果正好處理完畢,ACK和FIN也有可能同步發送。但是一般來說ACK和FIN是不同步的,所以一般叫做四次揮手