網路字節序和主機字節序

1.網絡傳數據的時候是一個字節一個字節的傳.字符串裏的每一個字符只用一個字節,前面的就先傳接收的後再解釋的時候也是按順序來所以字符串沒有網絡字節序的分別.

2.網絡字節序默認是大端,也就是說任何機器如果收到一個int型的4個字節,那麼這個機器就會認爲第一個字節是最高位,最後一個字節是最低位。

 

我們看看下面這個實例:

比如我們要傳個int數據,假設數據爲 

/*假設網絡連接已經建立好,網絡描述符爲fd*/

服務器:

...

int send = 1;

Write(fd, &send, sizeof(send));

我們看一下數據的傳遞過程,假設這一端主機是小端字節序,那麼這個過程應該是:

01

00

00

00

注:從左到右地址增大,這個是在用戶空間的擺放形式

Write後,數據被拷貝到內核驅動空間,形式還是一樣的。

01

00

00

00

注:從左到右地址增大

然後就是網卡驅動把這個字節發出去了,形式還是一樣。但是它是這樣來表現的,01字節先發,最後是00那個字節,這樣我們的服務器端的數據就分析完畢了。

客戶端:(大端主機字節序)

...

Int get = 0;

Read(fd, &get, sizeof(get));

一開始:

00

00

00

00

注:從左到右地址增大,這個是在用戶空間的擺放形式

Read的過程:

網卡驅動收到數據

01

00

00

00

,他知道是網絡傳過來的數據都是大端數據,所以他就解釋爲接受到了數據:0x01000000

因爲主機序也是大端,所以不轉換,直接把內核空間的數據拷貝到用戶空間,就爲:get=0x01000000.

結論:數據傳輸失敗。

那麼錯誤原因在哪裏呢?理由就是發送數據端應該先轉換爲網絡字節序;如果服務器端這樣寫:

服務器:

...

int send =  htonl(1);

Write(fd, &send, sizeof(send));

我們看一下數據的傳遞過程,假設這一端主機是小端字節序,那麼這個過程send的內容應該是:

00

00

00

01

注:從左到右地址增大,這個是在用戶空間的擺放形式

Write後,數據被拷貝到內核驅動空間,形式還是一樣的。

注:從左到右地址增大

然後就是網卡驅動把這個字節發出去了,形式還是一樣。但是它是這樣來表現的,00字節先發,最後是01那個字節,這樣我們的服務器端的數據就分析完畢了。

那麼在客戶端收到的數據分析就爲:

客戶端:(大端主機字節序)

...

Int get = 0;

Read(fd, &get, sizeof(get));

一開始:

00

00

00

01

注:從左到右地址增大,這個是在用戶空間的擺放形式

Read的過程:

網卡驅動收到數據

00

00

00

00

,他知道是網絡傳過來的數據都是大端數據,所以他就解釋爲接受到了數據:0x00000001(其實在這裏就決定了你的數據接受的是否正確,這裏成功解釋了,後面系統纔可以正確的進行字節序轉換)

因爲主機序也是大端,所以不轉換,直接把內核空間的數據拷貝到用戶空間,就爲:get=0x00000001.

結論:數據成功接受。所以傳輸數據的時候最好進行一下主機和網絡字節序的轉換。


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