1.TCP是面向鏈路的協議。在數據傳輸之前,需要通過三次握手建立TCP鏈路。數據傳輸完成後,需要通過四波釋放連接。
2.每個TCP通信都是在兩臺主機之間進行的,並且是點對點傳輸協議。
3.TCP提供可靠、無錯誤、無丟失、無重復和有序的到達服務。
4.TCP通信方可以在連接建立後的任何時候發送數據。TCP連接的兩端都設有發送緩沖區和接收緩沖區,用於臨時存儲雙向通信的數據。
5.面向字節流。在數據傳輸過程中,如果消息很長,TCP會分段傳輸數據。每個段的TCP傳輸信息都有該段的序列號,每個段包含壹部分字節流。接收端根據各段攜帶的序列號信息對數據進行拼接,最終拼接出初始傳輸數據。但是,在整個傳輸過程中,每個TCP段都攜帶有剪切的字節流數據。所以TCP是面向字節流的。
A.TCP和UDP以完全不同的方式發送消息。TCP並不關心應用程序壹次發送消息到TCP緩存多長時間,而是根據對方給定的窗口值和當前的網絡擁塞程度(UDP發送的消息長度由應用程序給定)來決定壹個消息段應該包含多少字節。
B.如果應用程序傳輸到TCP緩存的數據塊太大,TCP可以將其分成更短的塊,然後再傳輸。TCP還可以在構造消息段並將其發送出去之前等待足夠的字節積累。
每個字段的含義:
源端口:發送方的端口號。
目的端口:接收方的端口號。
序列號:TCP在分段傳輸傳輸的報文時會給每壹段加上壹個序列號,接收端也可以根據這個序列號判斷數據拼接的順序,主要用於解決網絡報告的亂序問題。
確認號:確認號是指接收端接收到數據後進行排序確認並發送下壹個期望接收的序號,數值=接收傳輸號+1。
數據偏移量:4位,表示數據的開頭離TCP段的開頭有多遠。其實就是TCP段頭的長度。由於報頭長度不固定,因此數據偏移字段是必需的。數據偏移量以32位為單位,因此TCP報頭的最大長度為60(15*4)字節。
控制位:
URG:該標誌表示TCP包的緊急指針字段有效,用於保證TCP連接不中斷,督促中間層設備盡快處理這些數據;
ACK:該標誌表示回復字段有效,也就是說上面提到的TCP回復號會包含在TCP包中;有兩個值:0和1。當它為1時,答案字段有效,否則為0。
PSH:這個標誌表示推送操作。所謂推送操作,是指數據包到達接收端後立即發送給應用,而不是在緩沖區排隊;
RST:這個標誌表示壹個連接重置請求。用於重置那些產生錯誤的連接,也用於拒絕錯誤和非法的數據包;
SYN:表示同步序列號,用於建立連接。SYN標誌位和ACK標誌位壹起使用。請求連接時,SYN=1,ACK = 0;連接響應時,SYN=1,ACK = 1;帶有此標誌的數據包通常用於端口掃描。掃描器發送壹個只有SYN的數據包。如果另壹臺主機響應數據包,則表明該主機擁有該端口。但由於這種掃描方式只是TCP三次握手的第壹次握手,所以這種掃描的成功意味著被掃描的機器不是很安全,安全的主機會強制進行TCP嚴格連接的三次握手;
FIN:表示發送方已經到達數據末端,即雙方數據傳輸完成,沒有數據要傳輸。發送帶有FIN標誌的TCP數據包後,連接將被斷開。帶有此標誌的數據包也經常用於端口掃描。
window:TCP中非常重要的機制,占2個字節,表示消息段發送方期望接收的字節數。可接受的序列號範圍從接收方的確認號到確認號和窗口大小之間的數據。後面會有例子解釋。
校驗和:校驗和包括偽頭、TCP頭和數據。TCP強制要求校驗和,由發送方計算並由接收方驗證。
緊急指針:當URG標誌為1時,緊急指針有效,表示需要先處理數據。緊急指針指示TCP段中緊急數據的最後壹個字節的序列號,以便接收方可以知道緊急數據有多長。
Option:最常用的選項是Maximum Segment Size (MSS),告知對方機器可以接收的最大TCP段長度。MSS選項僅在建立連接的請求中發送。
查看TCP在以太網幀中的位置
TCP包在IP包的有效載荷中。它的頭信息至少需要20個字節,所以TCP包的最大負載是1480-20 = 1460個字節。因為IP和TCP協議通常有額外的報頭信息,所以TCP負載實際上大約是1400字節。
因此,1500字節的消息需要兩個TCP包。HTTP/2協議的壹大改進是壓縮了HTTP協議的頭信息,使得壹個HTTP請求可以放在壹個TCP包中,而不是分成多個包,提高了速度。
以太網包負載為1500字節,TCP包負載約為1400字節。
壹個包是1400字節,所以壹次發送大量數據必須分成多個包。例如,壹個10MB的文件需要發送超過7100個數據包。
發送時,TCP協議對每個數據包進行編號(序列號,縮寫為SEQ),以便接收方按順序還原。萬壹丟包,也可以知道哪個包丟了。
第壹個數據包的編號是壹個隨機數。為了便於理解,這裏稱為包1。假設這個包的凈荷長度是100字節,可以推斷下壹個包的編號應該是101。也就是說,每個包可以得到兩個號碼:自己的號碼和下壹個包的號碼。因此,接收方知道應該以什麽順序將它們恢復到原始文件。
收到TCP包後,組裝和恢復由操作系統完成。應用程序不直接處理TCP數據包。
對於應用來說,不要在意數據通信的細節。除非線路異常,否則接收到的數據總是完整的。應用需要的數據放在TCP包中,有自己的格式(比如HTTP協議)。
TCP不提供任何機制來指示原始文件的大小,這是由應用層的協議規定的。例如,HTTP協議有壹個頭信息Content-Length,它表示信息體的大小。對於操作系統來說,就是不斷接收TCP包,按順序組裝,包很多。
操作系統不會處理TCP數據包中的數據。壹旦TCP包被組裝,它們就被移交給應用程序。TCP包中有壹個端口參數,用來指定要交給端口的應用。
當應用程序接收到組裝的原始數據時,以瀏覽器為例,它將根據HTTP協議的Content-Length字段正確地讀取數據片段。這也意味著壹個TCP通信可以包含多個HTTP通信。
服務器發數據包,當然是越快越好,最好壹次發完。但是如果發送太快,就有可能丟包。帶寬小、路由器過熱、緩存溢出等諸多因素都會導致丟包。線路不好,發的越快,丟的越多。
理想狀態是在線路允許的情況下達到最高速度。但是我們怎麽知道另壹條線的理想速度呢?答案是慢慢嘗試。
為了達到效率和可靠性的統壹,TCP設計了壹種慢啟動機制。剛開始傳輸慢,然後根據丟包情況調整速率:如果沒有丟包,則加快傳輸速度;如果數據包丟失,發送速度將會降低。
Linux內核設置為(常量TCP_INIT_CWND)。通信開始時,發送方壹次發送10個包,即“發送窗口”的大小為10。然後停下來等待接收方的確認再繼續發送。
默認情況下,每次接收到兩個TCP數據包時,接收方都會發送壹條確認消息。“確認”的英文單詞是acknowledgement,所以這個確認消息被縮寫為ACK。
ACK攜帶兩條信息。
有了這兩條信息,再加上發送方已經發送的數據包的最新編號,發送方就可以推斷出接收方的大致接收速度,從而降低或提高發送速度。這叫做“發送窗口”,這個窗口的大小是可變的。
註意,由於TCP通信是雙向的,雙方都需要發送ACK。雙方的窗口大小大概是不壹樣的。而且ACK只是幾個簡單的字段,通常和數據結合在壹起,在壹個數據包中發送。
即使是帶寬大,線路好的連接,TCP也總是從10包開始慢慢嘗試,過壹段時間就達到最高傳輸速率。這就是TCP的慢啟動。
TCP協議可以保證數據通信的完整性。這是怎麽做到的?
如前所述,每個數據包都帶有下壹個數據包的編號。如果沒有接收到下壹個數據包,ACK的編號將不會改變。
比如我們現在收到了4號包,但是沒有收到5號包。ACK將被記錄,期望接收包5。壹段時間後,收到數據包5,因此下壹輪ACK將更新該數字。如果仍然沒有收到5號包,但收到了6號或7號包,ACK中的數字不會改變,5號包將壹直顯示。這將導致大量重復內容的缺失。
如果發送方發現已經連續收到三個重復的ack,或者超時後還沒有收到任何ack,就會確認丟包,也就是第五個包丟失,然後重新發送這個包。通過這種機制,TCP確保不會丟失任何數據包。
TCP是壹個滑動窗口協議,即TCP連接的發送方在某壹時刻可以發送多少數據是由滑動窗口控制的,滑動窗口的大小實際上是由兩個窗口* * *。壹個是接收方的通知窗口,包含在TCP協議的報頭信息中,會和數據的ACK包壹起發送給發送方。這個值表示接收方的TCP協議緩存中還有多少空間。發送方必須確保發送的數據不超過這個剩余空間,以避免緩沖區溢出。接收器使用此窗口來限制流量。在傳輸過程中,通知窗口的大小與接收方處理取出數據的速度有關。另壹個窗口是發送方的擁塞窗口,由發送方維護,但不在協議頭信息中。滑動窗口的大小是通知窗口和擁塞窗口的較小值,因此擁塞窗口也被視為發送方用於流量控制的窗口。滑動窗口左邊緣向右移動稱為窗口關閉,發生在確認傳輸的數據時(此時表示數據已經被接收端接收,可以從發送端的發送緩沖區中取出),滑動窗口右邊緣向右移動稱為窗口打開,發生在接收進程從接收端的協議緩沖區中取出數據時。當發送方連續接收到發送數據的ACK包時,滑動窗口可以根據ACK包中的確認序列號和通知窗口的大小連續關閉和打開,使得滑動窗口向前滑動。如果接收進程壹直不取數據,就會出現0窗口現象,即滑動窗口的左邊緣和右邊緣重疊,此時窗口大小為0,無法再發送數據。
在TCP中,接收方(B)將向發送方(A)報告壹個窗口的大小,這個窗口稱為廣告窗口。
1.沒有B的確認,A可以連續發送窗口中的所有數據。所有發送的數據都已輸入
必須臨時保留它,直到收到確認,以便在超時重傳的情況下可以使用它。
2.發送窗口中的序列號表示允許發送的序列號。很明顯,窗口越大,發送方在收到對方確認之前可以繼續。
發送更多的數據,因此可以獲得更高的傳輸效率。但是接收機必須有時間處理接收到的數據。
3.發送窗口後沿的後部表示確認已被發送和接收。這些數據顯然不需要保留。
4.發送窗口前沿的前部表示不允許發送,因為接收方沒有為這部分數據預留臨時存儲緩沖空間。
5.發送窗口的後沿有兩種變化:靜止(沒有收到新的確認)和向前移動(收到新的確認)。
6.發送窗口的前沿有兩種變化:它保持向前移動或者它可能不移動(沒有接收到新的確認)。
TCP的發送方將重新發送發送的數據段,而不會在指定的時間內收到確認。重傳的概念很簡單,但是重傳時間的選擇確實是TCP中最復雜的問題之壹。TCP采用自適應算法,記錄發送消息段的時間和收到響應確認的時間。
這兩個時間之間的差異是消息段的往返時間RTT。TCP保持RTT的加權平均往返時間。超時重傳時間RTO比加權平均往返時間稍長。
RTT:
即往返時間,表示從發送方到接收方往返所需的時間。tcp在數據傳輸過程中會對RTT進行采樣(即測量發送的數據包與其ACK的時間差,並根據測量值更新RTT值,具體算法TCPIP詳述)。TCP根據獲得的RTT值更新RTO值。也就是說,重傳超時就是重傳間隔。發送方對每個發送的數據包進行計數。如果在RTO時間內沒有收到發送數據包的相應ACK,則任務數據包丟失,數據將被重新發送。通常,RTO值大於通過采樣獲得的RTT值。
如果接收到的消息段沒有錯誤,但不在序列號中,中間還有壹些序列號缺失的數據,是否可以嘗試只傳輸缺失的數據,而不重新傳輸已經正確到達接收方的數據?
答案是肯定的,選擇確認是可行的處理方式。
如果要使用選項來確認SACK,那麽在建立TCP連接的時候,就要在TCP頭的選項中加入“允許SACK”的選項,雙方必須事先約定。如果使用選擇確認,
那麽原始報頭中的“確認號碼字段”的用法保持不變。SACK文檔沒有規定發送方應該如何回復SACK。因此,大多數實施仍然會重新傳輸所有未確認的數據塊。
壹般來說,我們總是希望數據傳輸得更快,但如果發送方發送數據太快,接收方可能來不及接收,就會造成數據丟失。所謂流量控制,就是讓發送方的發送速率不要太快,讓接收方能夠及時收到。
計算機網絡中的鏈路容量、交換節點中的緩存和處理器都是網絡資源。在壹定時間內,如果網絡中對壹種資源的需求超過了該資源所能提供的可用部分,網絡的性能就會惡化。這種情況叫做擁堵。
擁塞控制方法:
1.慢啟動和擁塞避免
2.快速重傳和快速恢復
3.隨機早期檢測
1.起初,客戶端和服務器都處於關閉狀態。
2.首先,服務器主動監聽端口,並處於監聽狀態(例如,服務器開始監聽)。
3.客戶端發起SYN的連接,之後處於SYN-SENT狀態(第壹次握手,發送SYN = 1 ACK = 0 seq = x ack = 0)。
4.服務器接收發起的連接,返回SYN,確認客戶端的SYN,然後就處於SYN-RCVD狀態(第二次握手,發送SYN = 1 ACK = 1 SEQ = YACK = X+1)。
5.客戶端收到服務器發送的SYN和ACK後,發送ACK的ACK,然後就處於建立狀態(三次握手,send SYN = 0 ACK = 1 SEQ = X+1 ACK = Y+1)。
6.從客戶端收到ACK後,服務器處於已建立狀態。
(需要註意的是,有可能X和Y是相等的,都可能是0,因為它們代表的是每個發送消息段的序號。)
TCP連接釋放四個波。
1.目前,A和B都處於ESTAB化狀態。
2.A的應用進程首先向其TCP發送壹個連接釋放消息段,然後停止發送數據,主動關閉TCP連接。
3.B收到連接釋放消息段後發送確認,然後B進入關閉等待狀態。TCP服務器進程此時應該通知更高的應用程序進程,因此從A到B的連接被釋放。此時TCP連接處於半關閉狀態,即A沒有數據要發送。
B到A的連接沒有關閉,這種狀態可能會持續壹段時間。
4.收到B的確認後,A進入FIN-WAIT-2狀態,等待B發送的連接釋放消息..
5.如果B沒有數據發送給A,B發送連接釋放信號,然後B進入LAST-ACK狀態,等待A的確認。
6.再次收到B的連接釋放消息後,A必須確認,然後進入時間等待狀態。請註意,TCP連接還沒有釋放,A只有在時間等待定時器設置的2MSL後才會進入關閉狀態。
7。b收到a發送的確認消息後進入關閉狀態。
以百度為例,看看三次握手中真實數據的TCP連接建立過程。
再看四波吧。TCP斷開時會有四波,標誌位是FIN。我們在數據包列表中找到了相應的位置。理論上應該能找到四個包,但是我試了幾次,實際上只抓到了三個包。我查了壹下相關資料,說是因為服務器在發回客戶端的過程中,合並了連續發送的兩個包。所以下面就按照合並後的三波來解釋。請指出任何錯誤。
首先,當主機A的應用程序通知TCP數據已經發出時,TCP向主機B發送壹個帶有FIN標簽的報文段(FIN代表英文finish)。
第二步:主機B收到FIN段後,並不立即用FIN段回復主機A,而是先向主機A發送壹個確認序列號ACK,同時通知其對應的應用程序對方請求關閉連接(先發送ACK的目的是為了防止對方在此期間重新發送FIN段)。
第三步,主機B的應用告訴TCP:我要完全關閉連接,TCP向主機A發送FIN報文段..
步驟4:主機A收到這個FIN報文段後,向主機B發送ACK,表示連接完全釋放。
這是因為當服務器處於LISTEN狀態時,在接收到連接請求的SYN消息後,它將ACK和SYN在壹個消息中發送給客戶端。關閉連接時,當收到對方的FIN消息時,只表示對方不能再發送數據,但仍然可以接收數據,而我們自己壹方可能不會把所有的數據都發送給對方,所以我們可以立即關閉,也可以先發送壹部分數據給對方,然後再發送FIN消息給對方,以示我們同意現在關閉連接。因此,我們的ACK和FIN通常是分開發送的。
有兩個原因:
1.確保TCP協議的全雙工連接能夠可靠關閉。
其次,確保此連接的重復數據段從網絡中消失。
先說第壹點。如果直接關閉客戶端,由於IP協議的不可靠性或其他網絡原因,服務器沒有收到客戶端的最後回復。然後服務器會在超時後繼續發送FIN。此時,由於客戶端已經關閉,無法找到重傳FIN對應的連接。最後,服務器會收到RST而不是ACK,服務器會認為是連接錯誤,並向上級報告問題。這種情況雖然不會造成數據丟失,但是會導致TCP協議不滿足可靠連接的要求。因此,客戶端不直接進入CLOSED,而是保持TIME_WAIT。再次接收FIN時,能保證對方收到ACK,最終正確關閉連接。
其次,如果直接關閉客戶端,然後向服務器發起新的連接,我們無法保證這個新連接的端口號與剛剛關閉的連接的端口號不同。也就是說,新連接和舊連接的端口號可能是相同的。壹般來說,什麽都不會發生,但還是會有壹些特殊情況:假設新連接的端口號與關閉的舊連接的端口號相同,如果之前連接的壹些數據還卡在網絡中,那麽這些延遲的數據會在新連接建立後到達服務器。因為新連接和舊連接的端口號是相同的,而且因為TCP協議是以socket對為基礎來判斷不同的連接,所以TCP協議認為延遲的數據屬於新連接,會和真正的新連接的數據包混淆。所以TCP連接在TIME_WAIT狀態下要等待2倍的MSL,可以保證這個連接的所有數據都會從網絡上消失。
硬件速度
網絡和服務器負載
請求和響應消息的大小
客戶端和服務器之間的距離
TCP協議的技術復雜性
TCP連接建立握手;
TCP慢啟動擁塞控制;
數據聚合的Nagle算法;
用於捎帶確認的TCP延遲確認算法;
TIME_WAIT延遲和端口耗盡。
就是這樣。就這樣?
是的,就在這裏。
補充:
大部分內容都整理在網上,方便妳學習和復習。參考文章:
TCP協議簡介
TCP協議圖文詳解
什麽是TCP協議?
Wireshark數據包捕獲分析——TCP/IP協議
TCP協議的三次握手與四波
TCP協議的詳細解釋
TCP帶寬和延遲的研究(1)