C语言中的网络字节序和主机字节序

如果从网络中拿到一个以太网数据帧,把这个数据帧。用unsigned char buf数组保存然后逐个字节读取打印(类似 printf (buf[0]、printf (buf[2]、printf (buf[3])),这样是可以不去考虑 高位和低位的。

但是,如果使用了超过 1字节的变量去接受数据,比如 unsigned short 或者 unsigned int,那么就必须考虑高地位,主机字节序列,网络字皆序列。也就是单个字节内的高地位是不存在区别的,
但如果把两个字节拼到一起,正好就是反的。

据个列子

	// 下面为从原始数据包中打印TCP数据包头的源端口和目的端口 
	// 可以从帧格式中看到 34-38正好共4个字节的端口号
	//unsigned char raw_package 为原始网路数据包
    printf("src port is    %.2x%.2x\n",raw_package[34],raw_package[35]);
    printf("target port is %.2x%.2x\n",raw_package[36],raw_package[37]);
	//打印结果为 src port is 8704  target port is 01bb
	// 转为 10进制数字就需要的端口号了。

	// 再下面这个错误代码列子,可以表明没有字节序列转化的错误
	unsigned short package_double_byte_2[2];
    memcpy((void*)package_double_byte_2,raw_package + 34,4);
    printf("src port is    %0.2x\n",package_double_byte_2[0]));
    printf("target port is %0.2x\n",package_double_byte_2[1]));
	//打印结果为 src port is 0487  target port is bb01
	//可以看到结果与正确的十六进制端口号正好相反。
	/*
		显然当 使用 memcpy((void*)package_double_byte_2,raw_package + 34,4);
		的时候,机器默认给我使用了主机字节序列,
		但是从网络中拿到的原始数据包是 网络字节序列
	*/

解决方案:

  • ntohs,ntohl系列函数。
  • 如果还想原生秀操作可以去手动实现高地位转换 (蝶式交换法 参考 https://blog.csdn.net/weixin_34980267/article/details/117014258)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值