文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>long long 类型的网络字节顺序转换

long long 类型的网络字节顺序转换

时间:2006-07-04  来源:redfoxlinux

做过socket的都知道网络字节转换的事情,网络中传输的数据有的和本地字节存储顺序一致,而有的则截然不同,为了数据的一致性,就要把本地的数据转换成网络上使用的格式,然后发送出去,接收的时候也是一样的,经过转换然后才去使用这些数据,基本的库函数中提供了这样的可以进行字节转换的函数,如和htons( ) htonl( ) ntohs( ) ntohl( ),这里n表示network,h表示host,htons( ) htonl( )用于本地字节向网络字节转换的场合,s表示short,即对2字节操作,l表示long即对4字节操作。同样ntohs( )ntohl( )用于网络字节向本地格式转换的场合。随着c99标准的推行,我们伟大的c中增加了新的类型long long int ,unsigned long long int,都是64位的,怎么办?不转肯定是不行,就得自己想办法把它转了。当然有很多方法,我这里想使用一种递归的解决方法,证明咱也看过“艺术”。

  首先考虑网络字节转换的结果与原来有什么不同(我这里举的例子都是使用little endian的IA-32架构上面的Linux),如 int a = 0x12345678,b = htnl(a),那么就应该是0x78563412。如果是 short c = 0x1234,short d = 0x5678,e = htons(c),f = htons(d),这样e=0x3412,f=0x7856,如果能把e和f调换一下组合放在一起,不就是一个整型a(a=0x12345678)转换之后的值么。实验的代码如下:

#include <stdio.h>

struct ST{

    short val1;

    short val2;

};

union U{

    int val;

    struct ST st;

};

 

int main(void)

{

    int a = 0;

    union U u1, u2;

 

    a = 0x12345678;

    u1.val = a;

    printf("u1.val is 0x%x\n", u1.val);

    printf("val1 is 0x%x\n", u1.st.val1);

    printf("val2 is 0x%x\n", u1.st.val2);

    printf("after  first convert is: 0x%x\n", htonl(u1.val));

    u2.st.val2 = htons(u1.st.val1);

    u2.st.val1 = htons(u1.st.val2);

    printf("after second convert is: 0x%x\n", u2.val);

    return 0;

}

输出结果:

u1.val is 0x12345678

val1 is 0x5678

val2 is 0x1234

after  first convert is: 0x78563412

after second convert is: 0x78563412

按照这种想法我们实现long long int(64bit) 类型,把它分割成两个int(32bit) ,然后分别使用htonl(),分别转换,然后再从新组合数据。

代码如下:

#include <stdio.h>

struct ST{

    int val1;

    int val2;

};

union test {

    long long int val;

    struct ST st;

};

 

int main(void)

{

    long long int a;

    union test u1, u2;

 

    a = 0x7654321087654321LL;

    u1.val = a;

    u2.st.val2 = htonl(u1.st.val1);

    u2.st.val1 = htonl(u1.st.val2);

    printf("val1 is 0x%x\n", u2.st.val1);

    printf("val2 is 0x%x\n", u2.st.val2);

    printf("u1.val     is    : 0x%llx\n", u1.val);

    printf("after convert is : 0x%llx\n", u2.val);

   

    return 0;

}

执行结果:

val1 is 0x10325476

val2 is 0x21436587

u1.val     is    : 0x7654321087654321

after convert is  : 0x2143658710325476

              另外注意long long int 最大值是0x7fffffffffffffff,即7后面15个f(2的63次方减1) unsigned long long int 最大值是0xffffffffffffffff,16个f(2的64次方减1)。程序中long long int 可以简写为 long long,但是记住这是简写,就像long是long int的简写。

想看数据在内存中如何存储的,就用gdb吧!使用gdb中 x命令,如 x /xb &a表示要察看存储在变量a中的前一个字节(byte)中的数据(16进制)。x /xw &a 就是要察看变量a中前4个字节(word)数据(16进制)。x /xg &a 察看a开始8个字节的数据。自己去看看吧。

相关阅读 更多 +
排行榜 更多 +
PvZ戴夫的时空冒险重置

PvZ戴夫的时空冒险重置

策略塔防 下载
PVZTV雪版阳光加50

PVZTV雪版阳光加50

策略塔防 下载
双刃战士雪姐

双刃战士雪姐

冒险解谜 下载