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.
結論:數據成功接受。所以傳輸數據的時候最好進行一下主機和網絡字節序的轉換。