?
🔍 開發者資源導航 🔍 |
---|
🏷??博客主頁:?個人主頁 |
📚?專欄訂閱:?JavaEE全棧專欄 |
?本系列往期內容~
TCP/UDP協議深度解析(一):UDP特性與TCP確認應答以及重傳機制
TCP/UDP協議深度解析(二):TCP連接管理全解,三次握手四次揮手的完整流程
TCP/UDP協議深度解析(三):TCP流量控制的魔法—滑動窗口、擁塞控制與ACK的智慧
一、 粘包問題
因為TCP協議是面向字節流的,因此接收方收到的數據是一段連續的數據,接收方無法判斷那一段數據是一個整體,這一段連續的數據就像是“粘”在了一起,無法區分,而這就稱之為“粘包問題”。
?1.1 解決方法
該問題在傳輸層層面無解,想要解決這個問題需要站在應用層角度來解決。
1.約定包與包之間的分隔符
約定某一個字符作為該段數據的結束標志,例如使用換行符'\n'。
2.約定包的長度或格式
例如:約定包的前n個字節表示數據的長度?。
解決粘包問題是在自定義應用層格式的時候要考慮的問題,但是已經存在成熟的解決方案,例如:json、protobuf等,因此不必過多操心該問題。
?二、TCP連接時的異常情況處理
2.1 進程崩潰
四次揮手的進行并不依賴進程,因此如果某個進程崩潰,它和正常退出沒有本質區別,并不會出現異常情況。
2.2 主機關機
正常的關機都會先殺死用戶的進程,但是關機也需要一定的時間,如果這段時間內揮手結束,那么就和正常一樣,如果這段時間沒有揮完也是可以將連接釋放掉的。
2.3 接收方掉電
如果接收方掉電,發送方發送的信息將不會再收到ack,此時無論多少次的超時重傳都無法解決問題,當達到一定次數后,發送方會主動發送一個“復位報文”,重置TCP連接,如果還是收不到ack,那么發送方就會主動釋放掉連接。
?2.4 發送方掉電
如果發送方突然掉電了,接收方因為是被動的一方,無法確認對方現在是休息了還是掛掉了,因此他只能等待下去,但是并不會無限等待,超過一定的時間后會主動的發送“心跳包”,來確認對方的狀況。
心跳包并不包含載荷,他只是為了觸發對方的ack,如果沒有心跳就認為對方掛掉了,進行RST復位,再不行就會釋放掉該連接。
?