計算機存儲數據是按大端或者小端將數據保存在內存上. 通常處理器都只選擇其中的一種, 一般intel
和AMD
處理器都是採用小端存儲方式, 也有一些處理器是採用大端方式, 若是IBM
公司的處理器.編程
小端儲存 :網絡
0x1003 | 0x78 |
---|---|
0x1002 | 0x56 |
0x1001 | 0x34 |
0x1000 | 0x12 |
大端儲存 :函數
0x1003 | 0x12 |
---|---|
0x1002 | 0x34 |
0x1001 | 0x56 |
0x1000 | 0x78 |
大端跟小端存儲數據的方式就不同. 好比像0x12345678
, 在兩種方式的儲存如上. 小端 : 將高字節放在高位, 低字節放在低位. 大端 : 將高字節放在低位, 低字節放在高位. 若是咱們在傳輸數據的時候若是小端處理器傳送給大端處理器, 那麼在接收數據後都沒法辨認數據到底是什麼, 因此爲了保證數據能夠在不一樣的存儲方式上都可以被正確的接收, 規定網絡傳輸是大端傳輸, 當數據接收到本地時再根據處理器儲存數據的方式進行轉化, 這樣就保證接收後不會數據沒法辨認.ui
大端仍是小端的驗證有不少種方法, 這裏就簡單的用兩種方式來驗證.code
實驗一內存
大端跟小端是在儲存數據的方式上不同, 就像0x12345678
, 咱們將其中的低字節取出來查看是0x12
仍是0x78
就能夠驗證本機的使用的是小端仍是大端了.網絡編程
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i = 0x12345678; char ch = *(char *)&i; if(ch == 0x78) printf("小端\n"); else printf("大端\n"); exit(EXIT_SUCCESS); }
個人電腦驗證的是小端.it
實驗二io
咱們也能夠用union
來驗證, 原理與上面同樣的, 只是運用了union
自己就是直接共用儲存空間的.table
#include <stdio.h> #include <stdlib.h> #include <unistd.h> union tmp { int i; char ch; }; int main(int argc, char *argv[]) { union tmp t; t.i = 0x12345678; if(t.ch == 0x78) printf("小端\n"); else printf("大端\n"); exit(EXIT_SUCCESS); }
在網絡編程中, 可使用如下4個函數對數據在大小端之間進行轉換.
#include <apra/inet.h> uint32_t htonl(uint32_t); // 本機字節轉爲網絡字節(32位) uint32_t ntohl(uint32_t); // 網絡字節轉爲本機字節(32位) uint16_t htons(uint16_t); // 本機字節轉爲網絡字節(16位) uint16_t ntohs(uint16_t); // 網絡字節轉爲本機字節(16位)
網絡字節是大端方式. 上面函數的能夠這樣記 : h
表示host
(本機), n
表示network
(網絡), to
轉換, l
長字節, s
短字節.
可使用驗證一下 :
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { uint32_t l = 0x12345678; uint32_t ll = htonl(l); printf("ll = %x, l = %x\n", ll, l); // ll = 78563412, l = 12345678 exit(EXIT_SUCCESS); }
這裏僅僅用簡單的例子驗證本機的大小端, 重點明白