簡體   English   中英

發送數據包前讀取TCP序列號

[英]Reading TCP Sequence Number Before Sending a Packet

我正在Linux下編寫C / C ++客戶端-服務器程序。 假設消息m將從客戶端發送到服務器。

客戶端在發送m之前是否可以讀取將攜帶m的數據包的TCP序列號?

實際上,我想將此序列號附加到m,然后發送結果包。 (嗯,事情比較復雜,但是讓我們保持簡單。實際上,我想將身份驗證信息應用於此序列號,然后將其附加到m。)

此外,

服務器是否可以讀取攜帶m的數據包的TCP序列號?

您可以執行幾乎與此等效的操作。 您可以計算所發送的所有字節,並在消息末尾對消息之前發送的所有字節進行計數。

每當有人談論TCP的“數據包”時,我都會感到非常緊張。 因為如果同時談論數據包和TCP,那么您就在混合不應混合的協議級別。 您在TCP中發送的數據與通過IP發送的數據包之間沒有有意義的對應關系。

是的,IP數據包中有序列號用於發送TCP信息。 這些序列號是到目前為止已發送的字節數(又稱八位字節)的計數。 它們標識數據包中的字節在流中的哪個位置,但它們與數據包無關。

如果發生重發,或者您使用的是Nagle算法,或者當天的TCP協議棧感覺像這樣,那么您可能最終會在同一包中進行兩次發送操作。 或者,您可能會以一個發送操作的一半結束一個包,而在另一個數據包中結束一半。 每個數據包都有自己的序列號。

就像我說的,在傳輸層執行的發送操作與在網絡層發送的數據包之間絕對沒有任何有意義的關系。 從理論上講,我也不是。 這並不是“真正的所有數據包下面,除非有一些怪異的條件,否則發送一般都將所有字節放入單個數據包中”。 不,我在上面概述的場景中,將一次發送操作中的字節散布到多個數據包中的情況經常發生且在不可預測的條件下發生。

因此,我不知道您為什么想知道有關數據包中序列號的任何信息。 但是,如果您使用序列號作為發送字節數的代理,則可以自己計算該計數,然后自己將其填充到流中。 並記住也要計算這些字節。

不,您不能這樣做-至少不能達到預期的結果

這是因為:

  • TCP是基於流的,而不是基於數據包的。
  • TCP序列號以字節為單位 ,而不是數據包。
  • 基礎TCP層為您做分段。
  • TCP窗口大小/數據包大小是動態的

這意味着您可能會在序列號末尾發送序列號為“分組”的“分組”。 事實證明,潛在的魔術重新分割了您的數據包。

你想要什么:

    1   2   3   4
  +---+---+---+---+          
  | A | B | C |"1"|  packet 1, seq=1, len=4
  +---+---+---+---+          

    5   6   7   8
  +---+---+---+---+          
  | A | B | C |"5"|  packet 2, seq=5, len=4
  +---+---+---+---+          

您可能會得到:

    1   2   3   4         
  +---+---+---+---+ 
  | A | B | C |"1"|    packet 1 (seq=1, len=4)
  +---+---+---+---+ 

 (packet 1 got lost) 

    1   2   3   4   5   6
  +---+---+---+---+---+---+
  | A | B | C |"1"| A | B |   packet 1, resent, seq=1, len=6
  +---+---+---+---+---+---+ 

    7   8
  +---+---+
  | C |"5"|  packet 2, seq=7, len=2
  +---+---+

TCP / IP堆棧可以為您做所有事情。 您僅收到有效載荷。 堆棧會刪除所有標頭,並在用戶空間提供有效負載。

如果您確實想在數據包標頭級別添加或修改,請嘗試使用RAW sockets RAW套接字直接從網卡接收/發送數據包,而不考慮傳輸類型(TCP或UDP)。 在這種情況下,您必須剝離/添加所有標頭( TCP/UDP Header, IP Header and Ethernet Header )以及有效載荷。

RAW套接字上簽出非常好的視頻教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM