這個是轉載的,不過結合這個看更好https://www.cnblogs.com/freefish12/p/5394876.html
我是為了理解keep-live
TCP:傳輸控制協議
TCP是一種面向連接的、可靠的、基於字節流的傳輸層通信協議。
面向連接: 面向連接意味着使用tcp的應用程序在傳輸數據前必須先建立連接,就如打電話一樣,要先進行撥號,等待對方響應才能開始說話。
可靠性:tcp協議通過下列方式來提高可靠性:
- 應用數據被分割成TCP認為最適合發送的數據塊。這和UDP完全不同,應用程序產生的數據報長度將保持不變。由TCP傳遞給I P的信息單位稱為報文段或段
- 當TCP發出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。
- 當TCP收到發自TCP連接另一端的數據,它將發送一個確認。這個確認不是立即發送,通常將推遲幾分之一秒。
- TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。
- 既然TCP報文段作為IP數據報來傳輸,而IP數據報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的數據進行重新排序,將收到的數據以正確的順序交給應用層。
- 既然I P數據報會發生重復,TCP的接收端必須丟棄重復的數據。
-
TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發送接收端緩沖區所能接納的數據。這將防止較快主機致使較慢主機的緩沖
區溢出。字節流:兩個應用程序通過TCP連接交換8 bit字節構成的字節流。
另外,TCP對字節流的內容不作任何解釋。TCP不知道傳輸的數據字節流是二進制數據,還是ASCII字符或者其他類型數據。對字節流的解釋由TCP連接雙方的應用層解釋。
TCP首部格式
tcp數據是被封裝在IP數據包中的,和udp類似,在IP數據包的數據部分。tcp數據包的格式如下:
源端口號和目的端口號與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相似需要計算偽首部。
Wireshark抓包分析TCP結構
利用wireshark抓取一個tcp數據包,查看其具體數據結構和實際的數據:
TCP連接的建立
利用TCP傳輸數據前,需要建立tcp連接,tcp連接的建立有3個主要過程,叫做3次握手,具體過程如下圖所示:
過程:
1. 首先客戶端發送一個SYN包給服務器(SYN=1,Seq為主機選擇的這個連接的初始序號),然后等待應答。
2. 服務器端收到SYN包,回應給客戶端一個ACK =x+1、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。