LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1556|回复: 7

网络字节序的问题 大人请进

[复制链接]
发表于 2003-11-19 20:03:48 | 显示全部楼层 |阅读模式
最近接触到网络字节序的概念 查了查资料 不是很明白 先引用一段材料:

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的。因而对int、uint16、uint32等多于1字节类型的数据,在这些嵌入式平台上应该变换其存储顺序。通常我们认为,在空中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其它平台产品的互通,在程序中发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字节序转换为主机字节序。

在本LINUX的书里介绍到INTEL的CPU使用的小端字节序 其他比MOTOROLA
68000系列CPU使用的是大端字节序 如果不转换 将数据通过网络发出时 比如MOTOROLA发一个16位数据:0X1234 传送到INTEL时
就被INTEL解释为0X3412 也就是4660成了13330 所以有时候需要一些函数来进行大小端字节序的转换

关于这大小字节序的概念不是很想的明白 数据在
内存里是具体怎么存放的形式?为什么会有CPU解释的不同?数据不是按12345678……这样的顺序一直排列的么?希望大人赐教 谢谢
发表于 2003-11-19 22:00:18 | 显示全部楼层
好像只有x86特殊吧

这里有一段W. Richard Stevens的代码,用于判断字节序

/*
* gcc -Wall -pipe -O3 -s -o byte_order byte_order.c
*/
#include <stdio.h>
#include <stdlib.h>

/*
* return value:
*     1 big-endian
*     2 little-endian
*     3 unknow
*     4 sizeof( unsigned short int ) != 2
*/
static int byte_order ( void )
{
    union
    {
        unsigned short int s;
        unsigned char      c[ sizeof( unsigned short int ) ];
    } un;

    un.s = 0x0201;
    if ( 2 == sizeof( unsigned short int ) )
    {
        if ( ( 2 == un.c[0] ) && ( 1 == un.c[1] ) )
        {
            puts( "big-endian" );
            return( 1 );
        }
        else if ( ( 1 == un.c[0] ) && ( 2 == un.c[1] ) )
        {
            puts( "little-endian" );
            return( 2 );
        }
        else
        {
            puts( "unknow" );
            return( 3 );
        }
    }
    else
    {
        printf( "sizeof( unsigned short int ) = %u\n", ( unsigned int )sizeof(unsigned short int ) );
        return( 4 );
    }
    return( 3 );
}  /* end of byte_order */

int main ( int argc, char * argv[] )
{
    printf( "byte_order() = %d\n", byte_order() );
    return( EXIT_SUCCESS );
}  /* end of main */
发表于 2003-11-20 10:34:19 | 显示全部楼层
找本《结构化计算机组成》看看。
 楼主| 发表于 2003-11-20 22:12:09 | 显示全部楼层
谢谢2楼的代码 不过关键地方还是没看懂:(
这里
union
{
unsigned short int s;
unsigned char c[ sizeof( unsigned short int ) ];
} un;
un.s = 0x0201;

if ( ( 2 == un.c[0] ) && ( 1 == un.c[1] ) )
{
puts( "big-endian" );

0x0201的二进制是:1000000001
如果是big-endian时 不是un.c[0](第一个INT字节里)的8位是:00000010(前六个0是补位上的?) 后一字节里是00000001 这样第一个字节等于2 第二个字节等于1 而是小端字节时正好原后字节的00000001和00000010换了位置?因为2比1大 就是所谓的高字节大于低字节? 是这样的意思么?

不过这样理解的话 0X1234(二进制1001000110100)和0X3412(11010000010010)怎么解释?他俩怎么会变化呢?

由此引来的问题是比如一个二进制11111111000 占一个INT空间比如说是两个字节时 系统怎么堆放这些1和0的?两个字节有16位 怎么用11位来堆满16位呢?
谢谢
发表于 2003-11-21 09:07:31 | 显示全部楼层
所谓的big-endian跟little-endian不是数字高低字节值的比较
而是存储时的顺序先后问题。
以0x0201为例,在不平的平台下可以有不同的存储结果:
00000010 00000001
or
00000001 00000010
这两种存储情况就是所谓big-endian跟little-endian

x86平台下不存在11位的东西,如果一个对象可被寻址,那么它
的值或地址必定是8的倍数,因为x86的寻址单位是字节。
就像1一样,在存储器中它应该是;
00000001
or
0000000000000001
or
00000000000000000000000000000001
 楼主| 发表于 2003-11-21 13:17:15 | 显示全部楼层
谢谢楼上的 现在全懂了 谢谢
发表于 2004-4-15 22:45:53 | 显示全部楼层
大人请进

WHA DA YA MEAN!!!
发表于 2004-4-16 19:57:52 | 显示全部楼层
客套话而已,楼上的就别计较了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表