【Java 网络编程】TCP 连接 断开 机制 ( 三次握手 | 四次挥手 )
文章目錄
- I TCP 連接建立流程 ( 三次握手 )
- II SYN 和 ACK 中的隨機值
- III TCP 連接建關閉流程 ( 四次揮手 )
- IV TCP 連接斷開的保證
- V 四次揮手的必要性
I TCP 連接建立流程 ( 三次握手 )
1. 連接兩端點 : 客戶端 , 發起連接 ; 服務器端 , 等待客戶端的連接 ;
2. 初始狀態 : 客戶端發起連接 , 服務器端處于被動等待連接狀態 ;
3. 客戶端發送 SYN 命令 : 客戶端發起連接時 , 向服務器端發送 SYN 命令 ;
- ① 發送命令 : 客戶端向服務器端發送 SYN 命令 ( 連接請求命令 ) ;
- ② SYN 參數 : 該命令會攜帶一個隨機值參數 x , 該命令發送給服務器 ;
4. 服務器端收到 SYN 命令并處理 ( 第一次握手 ) : 服務器端收到 SYN 命令 , 向客戶端會送 SYN ACK 命令 ;
- ① 校驗命令 : 服務器端收到客戶端發送的 SYN 命令 , 會校驗該命令的正確性 ;
- ② 命令回送 : 如果 SYN 命令校驗通過 , 服務器端會送一條 SYN ACK 命令 ;
- ③ 命令組成 : 該 SYN ACK 指令包含兩個指令 , 即 接收到的 SYN 指令 , 和服務器端生成的 ACK 指令 ;
- ④ SYN 指令處理 : 服務器端收到客戶端發送的 SYN 指令 , 該指令有一個隨機值 x , 服務器端會送時 , 會將該 x 執行 +1 操作 ; 即會送的參數是 x + 1 ;
- ⑤ ACK 指令參數 : ACK 指令會自帶一個隨機值參數 y ;
5. 客戶端接收并處理 SYN ACK 命令 ( 第二次握手 ) : 客戶端收到服務器端會送的 SYN ACK 命令后 , 會先進行校驗 , 將 ACK 中的 y 參數執行自增操作 , 再次將 SYN ( x + 1 ) ACK ( y + 1 ) 命令發送給服務器端 ;
6. 服務器端收到 SYN ACK 命令 ( 第三次握手 ) : 服務器端再次收到客戶端的命令 , 校驗這兩個命令 , 校驗通過后 , 連接正式建立 ;
II SYN 和 ACK 中的隨機值
1. 服務器對應多個客戶端 : 服務器是需要接收很多客戶端的連接 , 那就需要針對不同的客戶端進行區分操作 , 這里從客戶端發送的隨機數有效的將該客戶端與其它客戶端進行了區別 ;
2. 連接舉例 : 客戶端 A 向服務器 S 發送 SYN 命令攜帶了隨機參數 X , 客戶端 B 向服務器 S 發送 SYN 命令攜帶參數 Y , X 和 Y 一定不能相同 ;
- ① 客戶端 A 發送 SYN 攜帶隨機數 X , 服務器 S 向客戶端 A 回送 X + 1 ;
- ② 客戶端 B 發送 SYN 攜帶隨機數 Y , 服務器 S 向客戶端 B 回送 Y + 1 ;
- ③ 如果服務器 S 回送的指令相同 , 那么連接的可靠性便不能保證了 ;
III TCP 連接建關閉流程 ( 四次揮手 )
1. 客戶端和服務器端都可以發起連接關閉的操作 , 這里拿客戶端發起關閉連接操作舉例 ;
2. 第一次揮手 ( 客戶端 -> 服務器端 ) : 客戶端當前狀態是已連接狀態 ( ESTABLISHED ) , 發送 FIN 命令 , 其會攜帶隨機參數 seq = u 的值 ;
SYN 是發起連接的命令 , FIN 是斷開連接的命令 ;
3. 第二次揮手 ( 服務器端 -> 客戶端 ) : 服務器端當前狀態也是已連接狀態 ( ESTABLISHED ) , 接收到 FIN 命令后 , 會向客戶端會送一條 ACK 命令 , 該 ACK 命令攜帶參數 ack = u+1 ;
4. 此時的服務器端狀態 : 客戶端發送請求斷開命令后 , 服務器端并不能馬上響應斷開 , 如果數據還沒有傳輸完 , 服務器端是不能斷開的 , 只能等到服務器端剩余數據傳輸完畢之后 , 服務器端才能第三次揮手 ;
5. 此時的客戶端狀態 : 客戶端接收到服務器端會送的 ACK 命令 ( ack = u + 1 ) , 此時客戶端的輸出連接就可以斷開了 , 客戶端不能進行輸出操作 , 此時無法向服務器端發送數據了 , 但是客戶端的輸入功能沒有關閉 , 客戶端還可以接收服務器端的數據 ;
6. 服務器端操作 : 服務器端有可能還有殘留數據沒有完全送達客戶端 , 此時將剩余數據傳輸給客戶端 , 客戶端目前是有接收功能的 ( 沒有發送功能 ) , 直到送達之后才會執行下一步操作 ;
TCP 是可靠傳輸 , 必須保證數據全部正確可靠 , 這個步驟是必須的 ;
7. 第三次揮手 ( 服務器端 -> 客戶端 ) : 服務器端將所有數據送出完畢后 , 向客戶端發送 FIN 命令 , 表示服務器端想要關閉連接了 ;
8. 第四次揮手 ( 客戶端 -> 服務器端 ) : 客戶端收到服務器端的 FIN 命令后 , 再次向服務器端會送 ACK 命令 , 表示服務器端可以斷開連接了 ;
第一次第二次揮手是客戶端向服務器端申請斷開連接 , 客戶端發送斷開請求命令 , 服務器端會送響應命令 ;
第三次第四次揮手是服務器端向客戶端申請斷開連接 , 服務器端發送斷開請求命令 , 客戶端會送響應命令 ;
IV TCP 連接斷開的保證
1. 服務器端保證第三次揮手能到達客戶端的機制 : 當服務器端向客戶端發送 FIN 命令后 ( 第三次揮手 ) , 服務器端會進入等待狀態 , 在等待狀態中 , 服務器端會以一個間隔周期持續發送 FIN 命令 , 這個間隔是一幀數據發送所需的最長時間 ( SML 默認 30 秒) , 如果超過 30 秒服務器端沒有收到客戶端會送的 ACK 命令 ( 第四次揮手 ) , 服務器端會再次發送 FIN 命令 ( 多次第三次揮手 ) , 直到收到客戶端會送的 ACK 命令 ( 第四次揮手 ) ;
2. 客戶端保證第四次揮手能到達服務器端機制 : 如果客戶端一直不向服務器端回送 ACK 命令 ( 第四次揮手 ) , 或者 ACK 命令未到達服務器端 , 服務器端會一直向客戶端發送 FIN 命令 ( 第三次揮手 ) , 客戶端不斷的收到 FIN 命令 , 不停地向服務器端發送 ACK 命令 , 直到服務器端收到 ACK 命令 , 停止向客戶端發送 FIN 命令 ;
V 四次揮手的必要性
1. 全雙工斷開 : 四次揮手保證了全雙工連接的安全斷開 , 全雙工指的是客戶端既可以接收服務器端的信息 , 也可以像服務器端發送消息 , 半雙工只能發送或者接收消息 , 不能同時發送和接收消息 ;
2. 前兩次揮手 : 這里的前兩次揮手是斷開客戶端向服務器端發送數據的連接 , 客戶端主動發起斷開 , 因此其不會再向服務器端寫出數據了 , 但是服務器端可能正在傳輸數據 , 因此這里還需要單獨處理客戶端接收數據的連接斷開的操作 ;
3. 傳輸剩余數據 : 前兩次揮手之后 , 客戶端就喪失了向服務器端發送消息的能力 , 但是服務器端還可以向客戶端發送消息 ; 利用這個空檔 , 客戶端需要將剩余的殘余數據發送給客戶端 , 然后主動發起斷開與客戶端的發送連接 ;
4. 后兩次揮手 : 后兩次揮手就是斷開服務器端向客戶端傳輸數據的連接 , 因此是服務器端發送斷開請求指令 ;
5. 不能是三次揮手 : 第二次和第三次揮手不能合并 , 因為第二次揮手后 , 無法保證服務器端可以馬上關閉連接 , 如果服務器端正在向客戶端發送數據 , 要確保最后一批數據能完整的送達客戶端 , 因此第二次揮手僅能代表客戶端向服務器端的連接關閉 , 不能強行關閉服務器端向客戶端傳輸數據的通道 , 需要等待數據傳輸完畢后 , 才能發起第三次揮手 , 第二次揮手和第三次揮手中間有一定的時間間隔 , 服務器端要利用這個間隔將剩余數據傳輸完畢 ;
6. 不能是五次揮手 : 目前需要斷開兩個連接 , 分別是發送和接收兩個雙工連接 , 每個連接段考只需要發送請求 FIN 指令 和 會送 ACK 指令即可完成 , 四次就可以完成兩個連接的斷開操作 , 多余的指令沒有必要 ;
總結
以上是生活随笔為你收集整理的【Java 网络编程】TCP 连接 断开 机制 ( 三次握手 | 四次挥手 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 网络编程】TCP API 简
- 下一篇: 【Java 网络编程】TCP 传输机制