您的位置:首页 > 理论基础 > 计算机网络

UNIX网络编程学习回顾---字节序

2012-07-26 09:32 288 查看
本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性。

参考资料:UNPV13e

来源:http://blog.csdn.net/rosetta

字节序的概念是最基础不过的,但这东西学了不经常用就忘,所以以后学习回顾后都记成笔记以备查询使用,并且也可以记录我近段时间的学习历程。

内存中存储数据有两种方法:一种是低字节存在低地址,高字节存在高地址,称为小端字节序(little-endian);另一种正常好相反,低字节存在高地址处,高字节存在低地址处。只要记住小端字节序:小高高(小代表小端,第一个高代表高字节,第二个代码高地址),那么另外一个大端自然而然就知道。一般情况下,网络字节序使用大端,intel x86主机序为小端。本文先画个草图,然后给出两个判断当前主机是小端还是大端的源码,结合代码就能更好理解和记忆。



低地址                       高地址
              ------------------------------------->
   小端字节序 |  低字节|        |        | 高字节  |
              ------------------------------------->
                        图1
  
   比如int a = 0x01020304,
   如果是小端,在内存中的分布就如下图2:
                低地址                       高地址
              ------------------------------------->
   小端字节序 |  0x04  |  0x03  |  0x02  |  0x01   |
              ------------------------------------->
                        图 2

   如果是大端,在内存中的分布就如下图3:
                低地址                       高地址
              ------------------------------------->
   大端字节序 |  0x01  |  0x02  |  0x03  |  0x04   |
              ------------------------------------->
                        图 3


代码一:

结合以上图2、图3,给出判断当前主机字节序的c源码:

//mybyteorder

#include <stdio.h>

int main(void)

{

int a = 0x01020304;//0x04相当于低字节,0x01为高字节。

if(*(char *)&a == 0x01)//如果a的首地址(即低地址)第一个字节长度地址存放的是高字节内容0x01,那么主机序为大端。

printf("big.\n");

else if(*(char*)&a == 0x4)//如果a的首地址一个字节长度地址存放的是低字节内容04,那么主机序为小端。

printf("small.\n");



return 0;

}

[root@xxx study]# gcc mybyteorder.c -Wall -o app

[root@xxx study]# ./app

small.

代码二(来到UNPV1e3):

此代码片段还可以理解union这个数据类型的使用,unp.h在UNPV1e3源码中都有,包括此代码也有。

UNPV1e3全书源码我已上传至下载资源中。

//byteorder.c

#include "unp.h"



int

main(int argc, char **argv)

{

union {

short s;

char c[sizeof(short)];

} un;



un.s = 0x0102;//0x02为低字节,0x01为高字节。

printf("%s: ", CPU_VENDOR_OS);

if (sizeof(short) == 2) {

if (un.c[0] == 1 && un.c[1] == 2)

printf("big-endian\n");

else if (un.c[0] == 2 && un.c[1] == 1)

printf("little-endian\n");

else

printf("unknown\n");

} else

printf("sizeof(short) = %d\n", sizeof(short));



exit(0);

}

[root@xxx intro]# make

gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o byteorder.o byteorder.c

gcc -I../lib -g -O2 -D_REENTRANT -Wall -o byteorder byteorder.o ../libunp.a -lpthread

[root@xxx intro]# ./byteorder

i686-pc-linux-gnu: little-endian

正因为保持代码一,是想看其对于非char类型进行char操作的过程,当然其可改成像代码二一样使用union的方法:

int main(void)

union{

int a;

char s[sizeof(int)];

}u;

u.a = 0x01020304;

if(u.s[0] == 0x01)

printf("big.\n");

else if(u.s[0] == 0x04)

printf("small.\n");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: