本篇文章主要對TCP原理進行簡單的分析和討論。服務器
TCP套接字中的I/O緩衝網絡
前文有介紹過TCP通訊數據無邊界的特性,即本端一次發送的數據對端並不必定一次性接收,那剩餘的數據在哪裏呢?函數
實際上,write函數調用後並不是當即傳輸數據,read函數調用後也並不是立刻接收數據。以下圖所示,write函數調用瞬間,數據將移至輸出緩衝區(適當的時侯傳向對方的輸入緩衝);read函數調用瞬間,從輸入緩衝區讀取數據。spa
TCP套接字的I/O緩衝3d
TCP的I/O緩衝有以下特色:blog
考慮這樣一種狀況,接收端輸入緩衝區大小爲50字節,而發送端輸出緩衝大小爲100字節,當發送端向接收端傳輸100字節的數據時會發生什麼呢?接收端緩衝區溢出?其實,接收端能夠正常處理這種狀況,由於TCP會控制數據流(Flow Control),這是由TCP協議的滑動窗口(Sliding Window)機制來保證的。同步
關於數據交換時調用的函數write和read(阻塞模式下),write函數調用的返回時機是發送端將數據傳輸至輸出緩衝區;read函數的返回時機是接收緩衝區有數據待讀取時。it
TCP內部工做原理1:與對方套接字的鏈接io
總體來看,TCP套接字從建立到消失所經歷的過程以下:原理
關於TCP套接字創建鏈接的過程以下圖所示,該過程就是所謂的三次握手(Three-way handshaking)機制。
TCP套接字鏈接過程
[SYN] SEQ:1000,ACK:-
首次創建鏈接請求時使用的消息字段爲SYN(Synchronization),即收發數據前傳輸的同步消息。SEQ值1000表示該數據包的編號,ACK字段爲空。
[SYN+ACK] SEQ:2000,ACK:1001
ACK是向對端的反饋字段,值1001表示已收到對端編號爲1000的消息。
經過數據包編號並確認的方式,能夠在數據丟失時立刻查看並重傳丟失的數據包,這也是TCP消息可靠的緣由。
關於三次握手中主機A最後一次ACK消息的討論,若該數據包丟失會發生什麼?
若最後的ACK消息丟失,服務器端(主機B)並不會重傳SYN+ACK消息,而是直接發送RST報文進入closed狀態,目的是爲了防止SYN泛洪攻擊;另外一個考慮,若最初客戶端主機A的SYN消息受網絡阻塞好久纔到達服務器端,而客戶端因爲長久未與服務端創建鏈接而關閉了套接字,則此時服務器端也不能收到ACK消息的迴應,所以也就不必重發SYN+ACK消息。
TCP內部工做原理2:與對方主機的數據交換
三次握手後雙方便創建了有效的鏈接,接下來是數據交換的過程,以下圖所示。
TCP套接字數據交換過程
以上通訊過程的消息字段和三次握手過程同樣,須要注意的是ACK消息字段的值是這樣計算的:SEQ值 + 傳遞的字節數 + 1。加1是爲了告知對方以前發送的消息已所有接收,下次可發送其他數據。若是數據包發生丟失又會怎樣?
TCP套接字數據傳輸錯誤處理
如上圖示過程,爲了完成數據包重傳,TCP套接字啓動計時器以等待ACK應答。若相應計時器發生超時(Time-out)則重傳。
TCP內部工做原理3:斷開與套接字的鏈接
TCP套接字的結束過程也很是優雅。若是對方還有數據須要傳輸時直接斷連會出問題,因此斷連時須要雙方協商。該過程以下圖所示,也即四次揮手(Four-way handshaking)的過程。
TCP套接字斷開鏈接過程
攜帶有FIN字段的數據包表示斷開鏈接,也就是說,雙方各發送一次FIN消息後斷開鏈接。