详解C语言的htons和htonl函数、大尾端、小尾端
在Linux和Windows网络编程时需要用到htons和htonl函数,用来将主机字节顺序转换为网络字节顺序。
在Intel机器下,执行以下程序
int main()
{
printf("%d /n",htons(16));
}得到的结果是4096,初一看感觉很怪。
解释如下,数字16的16进制表示为0x0010,数字4096的16进制表示为0x1000。 由于Intel机器是小尾端,存储数字16时实际顺序为1000,存储4096时实际顺序为0010。因此在发送网络包时为了报文中数据为0010,需要经过htons进行字节转换。如果用IBM等大尾端机器,则没有这种字节顺序转换,但为了程序的可移植性,也最好用这个函数。
另外用注意,数字所占位数小于或等于一个字节(8 bits)时,不要用htons转换。这是因为对于主机来说,大小尾端的最小单位为字节(byte)。
什么是大端模式(big-endian),为什么使用大端模式(big-endian)。
uint16_t htons(uint16_t hostshort);
htons的功能:将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian)
参数u_short hostshort: 16位无符号整数
返回值:TCP / IP网络字节顺序
htons 是把你机器上的整数转换成“网络字节序”, 网络字节序是 big-endian,也就是整数的高位字节存放在内存的低地址处。 而我们常用的 x86 CPU (intel, AMD) 电脑是 little-endian,也就是整数的低位字节放在内存的低字节处。举个例子吧。假定你的port是0x1234,在网络字节序里 这个port放到内存中就应该显示成addr addr+1,也就是:0x12 0x34;而在x86电脑上,0x1234放到内存中实际是:addr addr+1,也就是:0x34 0x12。htons 的用处就是把实际内存中的整数存放方式调整成“网络字节序”的方式。
第一个问题:为什么使用两个字节,也就是16位来存储。
这个简单一些,因为一个字节只能存储8位2进制数,而计算机的端口数量是65536个,也就是2^16,两个字节。
第二个为题:为什么计算机需要大端模式和小端模式?
小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。
|
|
大小尾端数据间的相互转换
/*
usage: to convert between the form of big-endian and little-endian
author: ydzhang
date: 2008年12月6日20:23:48
*/
#include <stdio.h>
typedef unsigned int u32;
typedef unsigned short u16;
#define BSWAP_16(x) \
(u16) ( ((((u16)(x) & 0x00ff)) << 8) \
| (((u16)(x) & 0xff00) >> 8) )
u16 bswap_16(u16 x)
{
return ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
}
u32 bswap_32(u32 x)
{
return ((x & 0x000000ff) << 24) |
((x & 0x0000ff00) << 8) |
((x & 0x00ff0000) >> 8) |
((x & 0xff000000) >> 24);
}
int main()
{
u16 num_16 = 0x1234;
u32 num_32 = 0x12345678;
printf("%x\n", bswap_16(num_16));
printf("%x\n", BSWAP_16(num_16));
printf("%x\n", bswap_32(num_32));
return 0;
}

详解C语言的htons和htonl函数、大尾端、小尾端的更多相关文章
- 详解go语言的array和slice 【二】
上一篇已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制sl ...
- 详解 Go 语言中的 time.Duration 类型
swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...
- 详解Go语言调度循环源码实现
转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...
- htons和htonl函数具体应用
htons和htonl函数具体应用 htons和htonl函数,是用来将主机字节顺序转换为网络字节顺序在进行网络抓包时,抓到的包的数据是网络字节顺序,在进行编程时,要进行主机字节顺序和网络字节顺序间的 ...
- Rserve详解,R语言客户端RSclient【转】
R语言服务器程序 Rserve详解 http://blog.fens.me/r-rserve-server/ Rserve的R语言客户端RSclient https://blog.csdn.net/u ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- 详解Linux运维工程师高级篇(大数据安全方向).
hadoop安全目录: kerberos(已发布) elasticsearch(已发布)http://blog.51cto.com/chenhao6/2113873 knox oozie ranger ...
- 详解C++中的多态和虚函数
一.将子类赋值给父类 在C++中经常会出现数据类型的转换,比如 int-float等,这种转换的前提是编译器知道如何对数据进行取舍.类其实也是一种数据类型,也可以发生数据转换,但是这种转换只有在 子类 ...
- Callback函数详解(我感觉,回掉函数的本质是函数指针,在业务做循环处理的时候,调用一下通知外部)
2010年的最后一天了,转载一篇自己认为还不错的文章与大家分享.希望对大家有所帮助. 一,回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度 ...
随机推荐
- QT学习第1天
QT学习第一天 坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...
- ELK Kafka json to elk
Logstash配置 input { kafka { zk_connect => "127.0.0.1:2181" topic_id => "clus ...
- android 获取本机SMI卡号码
//获取手机号码 TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); S ...
- Linux vim编辑命令
yum install -y vim-enhanced 安装vim 命令 一般模式 shift 4 行尾 shift 6 或 0行首 gg 顶部 G 下部 复制 yy 剪切几行 数字 dd p粘贴 ...
- linux开机自动连接无线网络
1.右击无线网络图标的“编辑连接”. 2.在“无线”选项卡里,选择“编辑”. 3.在“无线安全性”选项卡里,输入无线密匙,并选中左下角的“对所有用户可 用”的选项点击应用,会提 ...
- Python定时任务框架APScheduler 3.0.3 Cron示例
APScheduler是基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.基 ...
- 解决android中Layout文件下的xml文件配好后,R类中不能自动生成相应代码
不能更新的原因: 1.在xml文件中代码错误或者格式错误 2.eclipse 编译器是老版本 3.布局文件的文件名有大写字母 4.含有相同文件名.格式的xml文件 解决方法: 1.找到出错的xml文件 ...
- 网络之OSI&&TCP/IP比较
共同点: 1.OSI和TCP/IP都采用了层次结构的概念 2.都能够提供面向链接(TCP)和无链接(UDP)两种通信服务机制 不同点: 1.前者7层,后者两层 2.对可靠性要求不同,TCP/IP要求高 ...
- Unity游戏暂停之Update与FixedUpdate区别
游戏暂停 示例程序 下面这段代码演示游戏暂停 using UnityEngine; using System.Collections; public class GamePauseTest : Mon ...
- 如何配置QuickFIX/N
Acceptor或者Initiator能够为您维护尽可能多的FIX会话,因而FIX会话标识的唯一性非常重要.在QuickFIX/N中,一个FIX会话的唯一标识是由:BeginString(FIX版本号 ...