最近在項目中的soket通訊時,遇到了大小字節序問題和網絡傳輸時的字節序問題,如今給你們整理一下,但願你們對字節序有個比較深刻的瞭解,其實理解了就很簡單的。java
一、本地的數據經過網絡傳輸而後在目的地解析網絡上的數據,字節序是如何統一的linux
二、字節序不一樣,數據(如0xFF00)存入內存地址中位置不一樣(大字節序:FF--低地址位 00--高地址位 ;小字節序: 00--低地址位 FF--高地址位),爲何讀出的值都是0xFF00ios
大字節序:大端有效 ,高位數據先放入低地址內存 , 低位數據放入高地址內存windows
小字節序:小端有效,低位數據先放入低地址內存 , 高位數據再放入高地址內存 數組
注意:描述的是將數據(肉眼看到的)放入內存中的地址(計算機的硬盤內存中)網絡
而後看一下圖示吧:函數
相信你們對遇到的第二個問題已經知道結果了吧,如今再來看看第一個問題。ui
網絡字節序:是大字節序,在把數據進行網絡傳輸時,要保證本身傳輸到網絡上的數據時大字節序。this
再來看看圖示吧:spa
1號線路:發數據和接收數據都不須要轉序,由於本身是和網絡都是大字節序
2號線路:發數據和接收數據都須要轉序,由於本身是小字節序,網絡都是大字節序,才能保證本身本系統的數據永遠都是小字節序。可能高級語言(java、C#屏蔽了字節序,你們感覺不到,那是由於高級語言內存進行封裝和處理了)。
補充一下:若是發端和收端都是小字節序,能夠不轉序,可是這樣作可擴展不高,若是收端是大字節序的話,人家默認爲發過來的數據都是網絡字節序(大字節序),這樣處理就很混亂了。
好了,如今你們對第一個問題也清楚了吧。
最後讓咱們來看看鑑定大小字節序的C/C++語言程序吧
#include <stdlib.h> #include <string.h> int main() { /*將結合體的整型值賦值爲1,若是是小字節序,小端有效,低地址寫入的就是1,讀出字符ch就是1 若是是大字節序,大端有效,低地址寫入的就是0,讀出字符ch就是0*/ data.i = 1; if(data.ch) { printf("this system is small-endian\n"); } else { printf("this system is big-endian\n"); } return 0; }
緣由:將結合體的整型值賦值爲1,若是是小字節序,小端有效,低地址寫入的就是1,讀出字符ch就是1
若是是大字節序,大端有效,低地址寫入的就是0,讀出字符ch就是0
檢驗大小字節序的方法不少,本人認爲這個方法比較簡單,容易理解。
重要>>>字節序轉化,只是針對二字節、四字節的數據類型,對於單字節和數據區(本質也是單字節的數組)不須要轉化。
注意:在使用轉序函數時,函數內部會去判斷本機字節序,決定要不要轉
#include <iostream> using namespace std; /*windows下的頭文件;linux下是#include <arpa/inet.h>*/ #include<Winsock2.h> int main(int argc,char *argv[]) { /*經常使用方法(注意,在使用轉序函數時,內部會去判斷本機字節序,決定要不要轉) ****** host(本地)-->net(網絡): uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); ****** net(網絡) -->host(本地): uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); */ unsigned int srcNum = 0xff; unsigned int netNum = htonl(srcNum); printf("src-->net: srcNum=0x%x netNum=0x%x\n",srcNum,netNum); unsigned int toNum = ntohl(netNum); printf("net-->to : netNum=0x%x srcNum=0x%x \n",netNum,toNum); system("pause"); return 0; }
此代碼是在windows環境下編譯,若是編譯報錯:error LNK2019: 沒法解析的外部符號 _ntohl@4,緣由是沒有引入ws2_32.lib庫,只要在 項目->屬性->配置屬性->連接器->輸入 而後在附件依賴項添加ws2_32.lib
一、 IP(無符號整型,如0x80702101)在大、小字節序的系統中的內存是怎麼存放的(把這個IP當作4字節的數組unsigned char arry[4],則數組中每一個元素各是多少呢?)提示:數組的下標越大,地址就越大。
小字節:arr[0]=0x01 arr[1]=0x21 arr[2]=0x70 arr[4]=0x80
大字節:arr[0]=0x80 arr[1]=0x70 arr[2]=0x21 arr[4]=0x01
最後但願能對你們有幫助,有什麼問題請留言,謝謝。