tft每日頭條

 > 生活

 > 計算機網絡字節填充規則

計算機網絡字節填充規則

生活 更新时间:2024-10-11 16:58:09

通信過程(二)涉及到1字節内多個位段的網絡傳輸過程

本文主要分析涉及到位段的協議如何正确地從某個計算機(不論大小端)通過網絡傳輸到另一個計算機的過程。因為很多網絡實現都是以linux為内核的(事實上是因為我隻熟悉一點linux,其他的網絡操作系統不熟悉而已),linux是用C編寫的(事實上也是我隻熟悉C的原因),本文以C語言作為編程語言來分析傳輸過程。

說到網絡傳輸,相信沒有不熟悉TCP/IP的吧?當然這裡不是講網絡體系結構的,我們就以ip頭協議規範為例來看看它在網絡中的傳輸過程(其實這裡和TCP/IP沒什麼大關系,這裡就是傍個大概念而已,就像‘xx頭銜’。)。為簡單,我們隻分析前2個字節:

IP 頭的前2個字節(因為網絡序是BE,協議本身是因網而生的,所以協議得到定義也是BE的):

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)1

IP 頭的前2個字節

試想在一個大端的系統下(還記得大端系統的2個重要概念嗎?涉及到比特序和字節序),這段數據在内存中的排布是如何的?

排布如下(為了節省空間把4位的版本簡化寫成 ver或version, 4位首部長度簡化寫成ihl):

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)2

知道了内存的排布,用C語言如何定義呢?發現結構體的定義和位段(可能大部分教科書可能叫位域,我習慣用位段)很适合這個:

一般C語言教科書中很少涉及到定義的結構體的内存排布,這裡說明一下:

1、 C語言定義的結構體是從低内存開始排布的(不論大小端系統都是從低内存開始排布,注意這裡暫時不考慮C語言結構體對齊的問題,事實上這裡也不需要考慮)

2、 C語言定義的位段也是從低階開始排列,也就是前文說的低地址開始分布的(這裡也不論是否是大小端系統都是這樣排列的)

3、 在定義的位段中,賦值的話是個大小端系統有關系的,(大端系統LSB在高階(位段的高地址),小端系統相反)

4、 位序對于C語言是屏蔽的,也就是說在不同的端系統定義一個數,比如(0x12345678)做按位與、左移、右移操作,得到的值是一樣的。比如(0x12345678&0xff 得到的值都是0x78)

這幾點是C語言标準的規定,我理解的C語言是這樣規定的。所以這個就很簡單了,這個字段隻需要這樣定義就可以:

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)3

這樣我們的協議就定義出來了,下面我們再套用之前的圖,看一看這個iphdr是如何從大端發送到小端的吧,假設 version 字段為 0x4(0100b), ihl為0x5(0101b), tos 為 0x12(00010010b), 這些值隻是做傳輸實例,不一定有什麼特殊意義:

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)4

如果你仔細分析了上面這張圖,就會發現:咦好像有點不對啊,我要發送的值是(ver = 0x4, ihr = 0x5),怎麼到小端系統值變為了(ver = 0x5, ihr = 0x4)了呢?哪裡出問題了吧?你之前說的那些概念都有自己扯的吧!但這裡告訴你事實正是像傳輸的這樣的,我們已經用那些概念解決了字節序的問題,同樣這個問題也可以解決。那我們怎麼解決呢?用C實現很容易喽,還記得前面的那對宏定義嗎?__BIG_ENDIAN_BITFIELD 和 __LITTLE_ENDIAN_BITFIELD ,對,就是這一對。我們把它用上就可以了,像如下定義我們的結構體:

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)5

事實上我們的linux内核也就是這樣實現的。如果身邊有内核源碼,大家可以搜一下,内核中充斥着大量這樣的應用。有了這個,不再需要額外的知識,我們的圖也能自己完善了:

計算機網絡字節填充規則(計算機網絡傳輸字節序問題彙總)6

這就解決了所有問題了嗎?到現在為止,所有的概念我能想到的都介紹完了。當然如果看到此處的各位大神如果有要補充的歡迎補充,不勝感激。

但在實際的使用中還有一些問題需要補充,那就是C語言對于超過1個字節的位段的定義和在網絡通信中的使用。同樣根據上面的概念我們也可以比較容易(事實上對我這個笨蛋而言可能要推導很久)地推導出來。在下一節中我們來看看這種情況如何用C語言定義的以及傳輸的過程。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved