网络编程中大小端字节的使用剖析

最近在做rtmp流媒体网络发送的时候遇到了大小端的问题,也就是各位查看源码时经常看到的htonl, htons等。hton函数就是用作大小端转换的,说明如下:

htonl将主机数转换成无符号长整型的网络字节顺序。本函数将一个32位数从主机字节顺序转换成网络字节顺序。

另外大端字节序和小端字节序的定义和区别网络上也是一抓一大把,这里就不再啰嗦了。此篇文章主要的目的是分析为什么某些地方要使用hton函数做转换,为什么,以及为什么某些地方不使用。作者比较喜欢刨根究底,所以如果只是想使用该函数的朋友可以跳过下面的文字了。

首先看一个简单的语句: int len = 3;

类似语句估计大家都写过无数遍了,假设一个int占据4个字节,那么将3十六进制化后为:0x00 0x00 0x00 0x03,再假设在内存中len的首地址为0x01。由于大家使用的电脑芯片一般为intel的x86系列芯片,而x86芯片采用小端模式,所以编译运行后内存中的存储如下:

0x10---0x00

0x11---0x00

0x12---0x00

0x13---0x03

即高地址放低位。但是在网络发送中需要的大端序,即要求是按照:

0x10---0x03

0x11---0x00

0x12---0x00

0x13---0x00

这样的顺序存储才能正确发送出去int型的3。所以必须使用int len = htonl(3)来这样进行存储转换才能正确发送。也正因此,当变量长度为一个byte的时候,就没要使用hton函数来转换存储了,因为只占用一个地址。。。也因此,对于某些长度比较特殊的变量,大家会看到如下的语句:

number64 swap_number64(number64 n) {

    convert_u c;

    c.f = n;

    c.i = (((c.i & 0x00000000000000FFULL) << 56) |

           ((c.i & 0x000000000000FF00ULL) << 40) |

           ((c.i & 0x0000000000FF0000ULL) << 24) |

           ((c.i & 0x00000000FF000000ULL) << 8)  |

           ((c.i & 0x000000FF00000000ULL) >> 8)  |

           ((c.i & 0x0000FF0000000000ULL) >> 24) |

           ((c.i & 0x00FF000000000000ULL) >> 40) |

           ((c.i & 0xFF00000000000000ULL) >> 56));

    return c.f;

}

目的同样是用作网络发送前的大小端转换。

所以,总结就是大小端是为了网路发送前的内存转换而用的(一般主机的小端->网络的大端),一个字节没必要转换,直接复制或者memcpy就好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值