tcp頭部

TCP頭部


頭部長度:一般爲20字節,選項最多40字節,限制60字節。

這裏寫圖片描述

使用wireshark抓包的兩個tcp頭部如下,中括號表示註釋,不計算大小,

有選項,無載荷 

無選項,有載荷: 

  • 16位源端口號

16位說明什麼?

16位表明計算機最多隻有2^16 =65536個端口號。範圍是0-65535。注意端口0是保留端口,意思是它在TCP或者UDP傳輸中應該不會被用到。在unix socket編程當中,當建立新的TCP連接時,以端口號0來作爲連接參數來找到可用端口。

爲什麼要設計爲16位?

可能是因爲6萬多個端口足夠用了吧,太多了對性能有影響的

  • 16位目的端口號

端口號解決了從哪裏發和發給誰的問題

  • 32位序列號:用來標記數據段的順序,TCP會把要發送的報文段中每個字節都編上一個序號,第一個字節的編號由本地隨機產生,可能是0和4,294,967,295之間的任意值;給每個字節編完序號後,整個報文段的序列號seq就是這個報文段中的第一個字節的編號。

解決了數據排序的問題。哪個先發,哪個後發。每發送一次數據,就累加一次該數據的字節數大小,比如現在序列號爲1000,發送了1000,下一個序列號就是2000。

  • 32位確認號:下一次應該收到的數據的序列號,發送端收到這個應答後可以認爲在這個序號之前的數據都已被正常接收。

解決不丟包的問題。要確認對方是否收到。

  • 4位頭部長度(也叫數據偏移):它指出TCP 報文段的數據起始處距離 TCP 報文段的起始處有多遠。也就是頭部長度的意思。注意單位是32位,也就是4字節 。

4位最大可以表示爲1111,轉換爲10進製爲15。 所以tcp頭部最大爲4*15=60字節。

爲什麼頭部長度要限制爲4位呢?

再舉個栗子,如果該字段的值轉換爲十進制是5的話,說明這個tcp的頭部只有20字節,不包括選項部分。

  • 6位保留:主要是爲了以後擴展時使用,不用時設置爲0。當我們需要實現新的功能時,這6個bit可以提供相應的標識。
  • 6位標誌:TCP 是面向連接的,因而雙方要維護連接的狀態,這些帶狀態位的包的發送,會引起雙方的狀態變更。
  1. URG(uegent,緊急指針是否有效,可以理解爲是否有需要緊急處理的數據)、
  2. ACK(acknowledgement,是否爲ACK包,規定 除了最初建立連接時的syn包外,該位都應該設置爲1)、
  3. PSH(push,是否將數據推給上層協議,傳輸數據的時候會被設置爲1,三次握手過程中不會被設置。 1表示立即將數據傳給上層應用,0表示不需要立即傳而是存進緩衝區)、
  4. RST(reset,是否重置連接,1表示連接出現異常必須強制斷開連接,例如請求一個沒有被使用的端口,此時就可以返回一個RST爲1的包。此外程序宕掉或者切斷電源,連接被初始化,這種情況下,對方會發過來一個RST爲1的包來斷開連接)
  5. SYN(synchronize,是否爲同步序列號,只有從端點發出的第一個包纔會將該該置爲1。表示希望建立一個連接,並在其序列號的字段進行序列號初始值的設定)
  6. FIN(finish,1表示今後不會再有數據發送,希望斷開連接,當通信結束,希望斷開連接時,雙方就可以交換FIN位置爲1的tcp包,每個主機又對對方的FIN包進行ack後就可以斷開了。不過收到FIN後不必馬上回復一個FIN包,而是可以等到緩衝區中的所有數據都已成功發送而被自動刪除之後再發。)

網上查到的 保留位和標誌位的位數竟然有三種版本!

圖解tcp/ip中,是4位保留,8位標誌

維基百科 ,是 3位保留 9位標誌

百度百科和一些博客上,是6位保留,6位標誌。

不知道哪個是對的?

事實證明還是維基靠譜。。。

目前保留位的的後三位已經被使用作標識了,NSCWRECE。。。

  • 16位窗口大小:TCP流控制的一個手段,用來告訴對端TCP緩衝區還能容納多少字節。也就是從確認應答號開始能接受的數據大小,tcp不允許發送超過此處大小的數據,當窗口爲0的時候,此時發送端可以發送一個大小爲1的窗口探測包來了解最新的窗口大小。

TCP 要做流量控制,通信雙方各聲明一個窗口,標識自己當前能夠的處理能力,別發送的太快,撐死我,也別發的太慢,餓死我。

  • 16位校驗和:由發送端填充,接收端對報文段(包括tcp頭部和tcp數據)執行CRC算法以檢驗TCP報文段在傳輸中是否損壞。

三個協議都有 16 位的檢驗和(checksum),但有所區別。IP 的只是首部檢驗和,而 UDP 和 TCP 的檢驗和覆蓋全部數據。

原因在於 IP 數據包可能經過路由轉發。每一次轉發,首部字段都會被修改,從而需要重新計算檢驗和。假如 IP 的檢驗和覆蓋全部數據,重新計算的代價就太大了。IP 僅僅是首部檢驗和。而 UDP 和 TCP 的數據檢驗和只會在發送時計算一次,接受時計算一次,中間的路由過程都不需要計算。

另外 UDP 和 TCP 的檢驗和計算,並非僅僅計算自身的數據。還在前面附加了其它字段,稱爲僞首部。原文說的是“其目的是讓UDP兩次檢查數據是否已經正確到達目的地”。但這裏說得有點簡略,爲什麼需要兩次檢查呢?UDP 和 TCP 的數據是 IP 傳輸的,假如在 UDP(或 TCP)處發現數據並沒有正確到達目的地,唯一的可能性是 IP 層已經出錯了,而沒有檢測出來,因而而需要再次檢測。這種情況是有可能的,就是 IP 頭部的數據在傳輸過程中非人爲因素被改掉了,但 checksum 剛好不變。這時 TCP/UDP 只能靠自己再次檢測了。

  • 16位緊急指針:指到緊急數據的結束位。主要用途是傳輸一些緊急數據。 只有在控制位URG爲1時有效。 該字段的值表示本報文段中緊急數據的指針。也就是說,從數據部分的首位到緊急指針所指示的位置爲止,爲緊急數據。

  • 選項:用於提高tcp的傳輸性能,可有可無。最大長度爲40字節。

具有代表性的選項如下:

  1. 最大報文長度MSS(Maximum Segment Size),MSS是TCP數據包每次能夠傳輸的最大數據分段。爲了達到最佳的傳輸效能,TCP協議在建立連接的時候通常要協商雙方的MSS值,這個值TCP協議在實現的時候往往用MTU值代替(需要減去IP數據包包頭的大小20Bytes和TCP數據段的包頭20Bytes)所以一般MSS值1460。通訊雙方會根據雙方提供的MSS值得最小值確定爲這次連接的最大MSS值。(注意:最大報文段長度MSS這個名詞,很容易引起誤解。MSS是TCP報文段中的數據字段的最大長度。數據字段加上TCP首部纔等於整個的TCP報文段。所以MSS並不是TCP報文段的最大長度,而是:MSS=TCP報文段長度-TCP首部長度。
  2. 窗口擴大Window-Scale, 用於改善TCP吞吐量,tcp頭部中窗口大小隻有16位,也就是說在tcp包的往返時間內,只有發送最大64K字節(2的16次方-1 ,65535字節)的數據,如果採用了該選項,最大值可以擴展到1G字節。比如Window scale爲5,則窗口可以在Window字段的基礎上放大32 (2^5)倍。
  3. 時間戳Time Stamp: 用於高速通信中對序列號的管理,若要將幾個G的數據高速轉發到網絡中時,32位的序列號可能會迅速使用完,如果接收端對新老序列號產生混淆就無法實現可靠傳輸了。引入時間戳就可以區分新老序列號
  4. TCP 選項的格式。每個選項都有 kind 字段,表示類型;有 len 字段,表示長度。這種設計可以使新的選項兼容舊的實現。比如以後添加一種新選項,有個新的 kind 類型。舊的實現識別不了這個 kind 字段,就可以根據 len 來跳過這個選項,仍然可以正常運行。kind=1 的選項表示完全沒有操作,符號爲 nop(No Operation 的縮寫),可以充當填充字節,讓每個選項的開始儘可能以 4 字節對齊。

  • 填充:有選項的情況下,首部長度可能不是32比特的整數倍,爲此通過向字段填充0,來調整爲32位的整數倍

前面已經說過了,首部長度的單位是4字節。

  • 載荷:數據部分

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章