TCP:傳輸控制協議編程
TCP是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。
面向鏈接: 面向鏈接意味着使用tcp的應用程序在傳輸數據前必須先創建鏈接,就如打電話同樣,要先進行撥號,等待對方響應才能開始說話。
可靠性:tcp協議經過下列方式來提升可靠性: 服務器
TCP還能提供流量控制。TCP鏈接的每一方都有固定大小的緩衝空間。TCP的接收端只容許另外一端發送接收端緩衝區所能接納的數據。這將防止較快主機導致較慢主機的緩衝
區溢出。網絡
字節流:兩個應用程序經過TCP鏈接交換8 bit字節構成的字節流。數據結構
另外,TCP對字節流的內容不做任何解釋。TCP不知道傳輸的數據字節流是二進制數據,仍是ASCII字符或者其餘類型數據。對字節流的解釋由TCP鏈接雙方的應用層解釋。socket
TCP首部格式tcp
tcp數據是被封裝在IP數據包中的,和udp相似,在IP數據包的數據部分。tcp數據包的格式以下:
url
源端口號和目的端口號與udp中相似,用於尋找發端和收端應用進程。這兩個值加上IP首部中的源端IP地址和目的端IP地址惟一肯定一個TCP鏈接,在網絡編程中,通常一個IP地址和一個端口號組合稱爲一個套接字(socket)。
序號:用來標識從TCP發端向TCP收端發送的數據字節流,它表示在這個報文段中的的第一個數據字節。在tcp中tcp用序號對每一個字節進行計數(這個值與發送的幀數沒有關係,而是與發送的數據字節數有關係,後面會有說明)。
確認序號:包含發送確認的一端所指望收到的下一個序號。所以,確認序號應當是上次已成功收到數據字節序號加 1(不是單純的序號加1,還包括數據字節數)。
首部長度:用於記錄tcp數據報首部的長度,通常爲20字節,實際值爲首部長度除以4。
URG: 緊急指針( urgent pointer)有效。
ACK: 確認序號有效。
PSH: 接收方應該儘快將這個報文段交給應用層。
RST: 重建鏈接。
SYN: 同步序號用來發起一個鏈接。
FIN: 發端完成發送任務。
窗口大小:用於流量控制。
檢驗和:檢驗和覆蓋了整個的 TCP報文段: TCP首部和TCP數據,與udp類似須要計算僞首部。3d
Wireshark抓包分析TCP結構指針
利用wireshark抓取一個tcp數據包,查看其具體數據結構和實際的數據:blog
TCP鏈接的創建
利用TCP傳輸數據前,須要創建tcp鏈接,tcp鏈接的創建有3個主要過程,叫作3次握手,具體過程以下圖所示:
過程:
1. 首先客戶端發送一個SYN包給服務器(SYN=1,Seq爲主機選擇的這個鏈接的初始序號),而後等待應答。
2. 服務器端收到SYN包,迴應給客戶端一個ACK =x+一、SYN=1的TCP數據段(ACK表示確認序號有效,即收到上一個包,這裏加1並非ACK的值加1,ACK是一個標誌位,這裏會變成1,而x+1則是但願收到的下一個包的序列號,這個值放在包的確認序列號字段中,而只有ACK=1時,確認序列號纔有效)。
3. 客戶必須再次迴應服務器端一個ACK確認數據段(這裏的Seq爲x+1)。
通過上面3個過程就創建了一個tcp鏈接,接着就能夠發送數據了,由於創建鏈接使用了一個序列號x,因此發送數據的第一個字節序號爲x+1。
注意:這裏tcp爲應用層提供全雙工服務,意味數據能在兩個方向上獨立地進行傳輸,所以鏈接的每一段都有各自的傳輸數據序號(對應於上圖中的x和y,這兩個值是沒有必然聯繫的)。
Wireshark抓包分析TCP3次握手
下面經過利用http應用層鏈接一個網絡,實現tcp的3次握手和簡單的數據交換過程,下面經過抓包來實際觀察這個過程,首先咱們先看看抓到的包:
從第一行的tcp往下看,前面3個tcp包爲3次握手的過程,接着http包說明成功創建鏈接,主機向服務器發送一個http應用請求,服務器收到請求後,返回一個tcp確認幀,接着發送一個http應答給主機,主機收到服務器的http應答數據後,又發送一個tcp確認幀,確認收到了數據。這樣圖中的前7個包實現了主機和服務器創建鏈接,並實現一次簡單的數據請求應答過程。即下圖所示的交互按鍵回顯過程:
接下來是按照順序的7個數據幀的數據結構。數據幀順序分別爲:
1. 主機發起一個tcp鏈接請求(tcp),
2. 服務器響應鏈接請求(tcp),
3. 主機返回ACK完成3次握手成功創建鏈接(tcp),
4. 主機發送一個http網頁請求(http),
5. 服務器收到請求返回一個ACK幀(tcp),
6. 服務器根據請求發送數據到主機(http),
7. 主機收到服務器數據返回一個ACK幀(tcp),具體幀細節見下圖:
TCP鏈接的釋放
當通訊雙方完成數據傳輸,須要進行TCP鏈接的釋放,因爲TCP鏈接是全雙工的,所以每一個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的鏈接。收到一個 FIN只意味着這一方向上沒有數據流動,一個TCP鏈接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另外一方執行被動關閉。由於正常關閉過程須要發送4個TCP幀,所以這個過程也叫做4次揮手。具體過程以下圖:
過程(默認客戶端發起關閉):
1. TCP客戶端發送一個FIN,關閉客戶端到服務器端的數據傳送。(客戶端再也不發送報文給服務器端,但可接受服務器端報文)
2. 服務器收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1。
3.服務器關閉客戶端的鏈接,發送一個FIN給客戶端。(服務器端關閉到客戶端的數據傳送)
4.客戶段發回ACK報文確認,並將確認序號設置爲收到序號加1。
下面經過wireshark抓包瞭解具體的釋放鏈接過程,經過斷開一個鏈接,抓取到4個TCP幀,幀順序依次爲:
1. 主動關閉放發送一個FIN幀給被動方
2. 被動方收到關閉信息返回一個確認ACK幀
3. 被動方發送一個FIN幀給主動方
4. 主動方收到被動方的FIN關閉信息返回一個ACK幀,鏈接釋放
下面爲按照順序的幀數據結構詳細信息:
TCP的最大報文段長度
上面介紹了TCP鏈接的創建和釋放過程,下面介紹一下TCP的最大報文段長度。
最大報文段長度(MSS)表示TCP傳往另外一端的最大塊數據的長度。當一個鏈接創建時,鏈接的雙方都要通告各自的MSS。通常來講,MSS越大越好,由於報文段越大容許每一個報文段傳送的數據就越多,相對IP和TCP首部有更高的網絡利用率。
MSS選項只能出如今SYN報文段中,因此只能在SYN=1的幀中才會有MSS選項說明報文的最大段長度。
具體參考:
http://baike.baidu.com/link?url=c-fTckuehGMSiI5c2xCQDe3MUOKRwgdK6Q4CeO3tms8s6V3hIv5OmOQvUJvp67e90jUDAIjZfmhk8deiIjw1tK
其餘
關於TCP的內容還有不少,這裏再也不詳細說明,可是須要知道,TCP鏈接的創建和釋放還有幾種比較特殊的狀況,同時打開(SYN)創建鏈接,同時關閉或半關閉來釋放鏈接的狀況都是存在的,還有一些TCP的可選字段,這裏都再也不講了,具體能夠參考:TCP/IP 詳解卷1。