閱讀965 返回首頁    go 技術社區[雲棲]


TCP協議 及 TCP粘包現象

TCP協議 及 TCP粘包現象

TCP,Transmission Control Protocol,傳輸控製協議。這是一個麵向連接的傳輸層協議。
與之相對的無連接協議為UDP,用戶數據報協議。
傳輸層的基本數據單位為——報文。網絡層——包。數據鏈路層為——幀。物理層——比特。
TCP提供麵向連接的可靠服務,傳送數據之前必須先建立連接,傳送完畢要釋放鏈接。
服務器端使用的端口號:熟知端口號——0~1023;登記端口號——1024~49151.
客戶端使用的端口號——49152~65535。這種端口號僅在客戶進程運行時才動態確定。當服務器進程收到客戶端進程的報文時,就知道了客戶進程使用的端口號。
TCP協議是點對點的,提供不丟失、不重複、無差錯的可靠傳輸。
TCP提供全雙工通信允許通信雙方的進程在任何時候都能發送數據。兩個進程都設有發送緩存和接收緩存。
TCP的可靠傳輸是建立在不可靠的IP層之上的,這很神奇。依靠的措施是——報文確認和超時重傳。

1.TCP報文格式

圖1-1 Tcp報文的首部與數據

序號。TCP是麵向字節流的,TCP傳送的每一個字節都有編號。
確認號(小寫ack)。期望收到對方下一個報文段的數據部分第一個字節的編號。
數據偏移。指出本TCP報文段的數據部分距離初始部分有多遠。實際上也就是首部的長度。
ACK。值為1時確認號才有效。也就是說,建立連接後所有的報文段都必須把ACK置為1。
PSH。若psh為1,報文段直接發送,不再等緩衝區滿了再向下交付。
RST。複位標識。若TCP鏈接出現嚴重差錯,則重連。
SYN。同步標識,若為1,表明這是連接報文或同意連接報文。
FIN。終止標識,表示釋放一個連接。
接收窗口。告訴發送方自己接收區的緩存大小。
校驗和。檢驗整個報文段。注意區分的是,IP數據報的校驗和隻檢驗IP數據報首部。
最大報文段長度MSS。指數據部分的最大長度,加上首部長度才是整個TCP報文段的最大長度。

2.TCP的擁塞控製

1.慢開始和擁塞避免。
2.快重傳和快恢複。


3.TCP的建立鏈接

圖3-1 三次握手

4.TCP的連接釋放

圖4-1 四次握手


:為什麼斷開連接需要4次握手呢?

答:tcp是全雙工模式,接收到FIN時意味將沒有數據再發來,但是還是可以繼續發送數據。

5.粘包現象

TCP粘包問題。
TCP提供的是可靠的字節流服務。假設TCP接收方是B,發送方是A。
理想情況下,B每次read的都是A每次write的內容,但事實不是這樣的。
會出現A第一次發送(write)qwer這個字節流,第二次發送tyui;而B第一次讀到(read)的是qwe,第二次read的是rt,第三次read的是yui這種情況。
微笑為什麼呢?
應用層的數據交給TCP,會被分割再包裝成TCP報文,再加上下麵IP層的緩衝區處理、網絡擁塞等狀況,就會發生上麵的情況。
微笑應對方法
應用層發送“你好”,假設對應的字節數組是[1,2,3,4],那麼處理後交給TCP的是 [0,4,1,2,3,4],前兩個byte固定放本次傳輸數據量的大小。TCP接收端再寫一個相應的函數,依據長度提取字節就可以啦。
微笑我的處理
親測成功(測試中隻有描述尺寸的頭部 分兩次 被read()到的情況沒出現過)

最後更新:2017-04-03 05:39:29

  上一篇:go Log4j 2.0在開發中的高級使用詳解—SocketAppender的遠程輸出(五)
  下一篇:go Linux內核剖析 之 曆史和體係結構分析