C++实现主机字节序和网络字节序转换示例

 更新时间:2023年11月02日 11:37:11   作者:点墨  
这篇文章主要为大家介绍了C++实现主机字节序和网络字节序转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

字节序问题

现代CPU一次至少能装载4字节(32位机),即一个整数,这4个字节在内存中的排列顺序将影响它的值。这就是字节序问题。字节序分为大端字节序(big endian)和小端字节序(little endian)。

如上图,大端字节序是指数据的高位存在内存的低地址处,小端字节序是指数据的高位存在内存的高地址处。

现代PC大多采用小端字节序

当格式化的数据需要在两台使用不同字节序的主机进行传递时,接收端会错误的处理。解决的方法是:发送端将发送的数据转换成大端字节序然后发送,接收端根据自己的字节序决定需不需要处理(小端转换,大端不处理)。

在做网络编程的时候,使用提供的库即可进行转换(linux库,windows下是一样的,头文件有所区别)

#include <netinet/in.h>
unsigned long int _htonl(unsigned long int hostlong);
unsigned short int _htons(unsigned short int hostshort);
unsigned long int _ntohl(unsigned long int netlong);
unsigned short int _ntohs(unsigned short int netshort);

互换数据

如果平台没有提供这套,那么可以自己实现一下,原理很简单,就是互换下数据

#include <stdint.h>
#define BigLittleSwap16(v) ((0xFF00 & (uint16_t)(v)) >> 8 | (0x00FF & (uint16_t)(v)) << 8)
#define BigLittleSwap32(v) ((0xFF000000 & (uint32_t)(v)) >> 24 | (0x00FF0000 & (uint32_t)(v)) >> 8 | (0x0000FF00 & (uint32_t)(v)) << 8 | (0x000000FF & (uint32_t)(v)) << 24) 
#define BigLittleSwap64(v) ((0xFF00000000000000 & (uint64_t)(v)) >> 56 |(0x00FF000000000000 & (uint64_t)(v)) >> 40 |(0x0000FF0000000000 & (uint64_t)(v) )>> 24 |(0x000000FF00000000 & (uint64_t)(v)) >> 8 |(0x00000000FF000000 & (uint64_t)(v)) << 8| (0x0000000000FF0000 & (uint64_t)(v)) << 24 | (0x000000000000FF00 & (uint64_t)(v) )<< 40 | (0x00000000000000FF & (uint64_t)(v) )<< 56 )
int isCPUBigEndian(){
    union Data{
        short val;
        char byte;
    } data;
    data.val = 0x0102;
    return (data.byte == 0x01);
}
unsigned long int _htonl(unsigned long int hostlong);
unsigned short int _htons(unsigned short int hostshort);
unsigned long int _ntohl(unsigned long int netlong);
unsigned short int _ntohs(unsigned short int netshort);
unsigned long int _htonl(unsigned long int hostlong){
    return isCPUBigEndian() ? hostlong : BigLittleSwap32(hostlong);
}
unsigned short int _htons(unsigned short int hostshort){
    return isCPUBigEndian() ? hostshort : BigLittleSwap16(hostshort);
}
unsigned long int _ntohl(unsigned long int netlong){
    return isCPUBigEndian() ? netlong : BigLittleSwap32(netlong);
}
unsigned short int _ntohs(unsigned short int netshort){
    return isCPUBigEndian() ? netshort : BigLittleSwap16(netshort);
}

测试

#include <netinet/in.h>
#include <stdio.h>
int main(int argc,const char*argv[]){
   long int v1 = 0x11223344;
   short int v2 = 0x1122;
   printf("the endian of system is:%s\n",isCPUBigEndian()?"Big Endian":"Little Endian");
   printf("htonl:%x , %x , %x\n",v1,htonl(v1),_htonl(v1));
   printf("htons:%x , %x , %x\n",v2,htons(v2),_htons(v2));
   printf("ntohl:%x , %x , %x\n",v1,ntohl(v1),_ntohl(v1));
   printf("ntohs:%x , %x , %x\n",v2,htons(v2),_htons(v2));
    return 0;
}

在linux下的测试结果如下图

以上就是C++实现主机字节序和网络字节序转换示例的详细内容,更多关于C++主机网络字节序转换的资料请关注脚本之家其它相关文章!

相关文章

  • C语言实现数组元素排序方法详解

    C语言实现数组元素排序方法详解

    这篇文章主要为大家介绍了C语言算法练习中数组元素排序的实现方法,文中的示例代码讲解详细,对我们学习C语言有一定帮助,需要的可以参考一下
    2023-02-02
  • C语言基于EasyX库实现有图形界面钟表

    C语言基于EasyX库实现有图形界面钟表

    这篇文章主要介绍了C语言基于EasyX库实现有图形界面钟表,直线转动端点计算,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 解决pip install dlib报错C++11 is required to use dlib

    解决pip install dlib报错C++11 is required to use dlib

    这篇文章主要介绍了在使用pip install dlib安装dlib的时候报错C++11 is required to use dlib的解决方法,需要的的小伙伴可以参考一下,希望对你有所帮助
    2022-02-02
  • C++ map与set封装实现过程讲解

    C++ map与set封装实现过程讲解

    set set是一种关联式容器,下面这篇文章主要给大家介绍了关于C++中map和set使用的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友可以参考下
    2023-03-03
  • C++字符数组的输入输出和字符串结束标志使用讲解

    C++字符数组的输入输出和字符串结束标志使用讲解

    这篇文章主要介绍了C++字符数组的输入输出和符串结束标志使用讲解,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • Qt QFtp客户端实现上传下载文件

    Qt QFtp客户端实现上传下载文件

    本文主要介绍了Qt QFtp客户端实现上传下载文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C++实现LeetCode(109.将有序链表转为二叉搜索树)

    C++实现LeetCode(109.将有序链表转为二叉搜索树)

    这篇文章主要介绍了C++实现LeetCode(109.将有序链表转为二叉搜索树),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ 智能指针代码解析

    C++ 智能指针代码解析

    这篇文章主要介绍了c++ 智能指针基础的相关资料,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下,希望能给你带来帮助
    2021-10-10
  • C++常用字符串函数大全(2)

    C++常用字符串函数大全(2)

    这篇文章主要给大家分享的是C++常用字符串函数的大全,cstring.h库即C语言中的string.h库,它是C语言中为字符串提供的标准库。C++对此进行了兼容,所以我们在C++当中一样可以使用,下面文章的详细内容,需要的朋友可以参考一下
    2021-11-11
  • 浅谈C++ Explicit Constructors(显式构造函数)

    浅谈C++ Explicit Constructors(显式构造函数)

    下面小编就为大家带来一篇浅谈C++ Explicit Constructors(显式构造函数)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12

最新评论