C++网络编程之字节序

概述

        字节序是指多字节数据在内存中的存储顺序。主要有两种字节序:大端序、小端序。

        大端序:即Big-Endian,高位字节存放在低地址处,低位字节存放在高地址处。比如:16位整数0x1234,在大端序下会以0x12 0x34的形式存储。

        小端序:即Little-Endian,低位字节存放在低地址处,高位字节存放在高地址处。比如:16位整数0x1234,在小端序下会以0x34 0x12的形式存储。

        需要注意的是:不同计算机系统可能使用不同的字节序来存储多字节的数据类型。当这些系统之间进行通信时,如果不正确处理字节序问题,就可能会导致数据解析错误。比如:如果一台机器是小端序,另一台是大端序,它们之间的数据交换如果没有经过适当的转换,接收方可能会误解发送方的数据。

检测字节序

        在C++中,检测字节序有几种不同的方法。下面,分别进行介绍。

        1、使用类型转换。下面的代码封装了一个IsLittleEndian的函数,用于判断是否为小端序。在该函数中,首先初始化一个32位无符号整数uiValue,其值为0x01020304。然后,使用reinterpret_cast将uiValue的地址转换为char*类型的指针,以便逐字节访问。检查uiValue的第一个字节是否为0x04,如果是,则系统是小端序;否则,系统是大端序。

#include <iostream>
using namespace std;bool IsLittleEndian()
{unsigned int uiValue = 0x01020304;char* pValue = reinterpret_cast<char*>(&uiValue);// 如果第一个字节是0x04,则是小端序return (pValue[0] == 0x04);
}int main()
{if (IsLittleEndian()){cout << "Little-Endian" << endl;}else{cout << "Big-Endian" << endl;}return 0;
}

        2、使用联合体。联合体允许我们在相同的内存位置存储不同的数据类型,这样可以方便地检查多字节数据类型的字节顺序。在下面的代码中,我们首先使用联合体将一个32位无符号整数unsigned int i和一个4个字符的数组char c[4]共享同一块内存。然后,初始化联合体中的unsigned int i为0x01020304。最后,通过char c[4]访问unsigned int i的第一个字节。检查第一个字节是否为0x04,如果是,则系统是小端序;否则,系统是大端序。

#include <iostream>
using namespace std;bool IsLittleEndian()
{union {unsigned int i;char c[4];} value = {0x01020304};// 如果第一个字节是0x04,则是小端序return (value.c[0] == 0x04);
}int main()
{if (IsLittleEndian()){cout << "Little-Endian" << endl;}else{cout << "Big-Endian" << endl;}return 0;
}

        3、使用标准库函数。在某些情况下,可以使用标准库提供的函数来检测字节序。比如:在POSIX兼容的系统中,可以使用endian.h头文件中的宏来检测字节序。具体如何使用,可参考下面的示例代码。

#include <iostream>
#include <endian.h>
using namespace std;int main()
{
#if __BYTE_ORDER == __LITTLE_ENDIANcout << "Little-Endian" << endl;
#elif __BYTE_ORDER == __BIG_ENDIANcout << "Big-Endian" << endl;
#elsecout << "Unknown endianness" << endl;
#endifreturn 0;
}

主机字节序与网络字节序

        主机字节序是指当前计算机系统中,多字节数据类型的存储顺序。主要有上面介绍的两种字节序:大端序和小端序。

        在网络协议中,为了确保数据的一致性,通常规定使用一种统一的字节序。最常见的网络字节序是大端序,这是因为:大端序与人类阅读数字的习惯一致,便于调试和理解。比如:在TCP/IP协议族中,所有多字节的数据类型都要求使用大端序进行传输。

字节序转换

        在跨平台或异构网络环境中,不同的系统可能使用不同的字节序。如果发送方和接收方的字节序不一致且没有进行适当的转换,会导致数据解析错误。因此,在网络编程中,必须确保数据在发送前转换为网络字节序,在接收后转换回主机字节序。

        C++标准库提供了几个用于字节序转换的函数。对于POSIX兼容系统(比如:Linux、Mac等),这些函数定义在arpa/inet.h头文件中。对于Windows系统,这些函数定义在winsock2.h头文件中。

        htons()和htonl():用于将主机字节序转网络字节序(Host to Network Short/Long)。

        ntohs()和ntohl():用于将网络字节序转主机字节序(Network to Host Short/Long)。

        在下面的示例代码中,我们使用htons和htonl将主机字节序的hostShort、hostLong转换成了网络字节序的netShort、netLong。然后,再将网络字节序的netShort、netLong转换回主机字节序的convertedShort、convertedLong。注意:在Windows下使用Visual Studio编译这段程序时,需要在工程中链接ws2_32.lib库,否则链接时会报错。

#include <iostream>
#include <winsock2.h>
using namespace std;int main()
{// 主机字节序转为网络字节序uint16_t hostShort = 0x1234;uint32_t hostLong = 0x12345678;uint16_t netShort = htons(hostShort);uint32_t netLong = htonl(hostLong);cout << "Host short: " << hex << hostShort << endl;cout << "Network short: " << hex << netShort << endl;cout << "Host long: " << hex << hostLong << endl;cout << "Network long: " << hex << netLong << endl;// 再将网络字节序转回主机字节序uint16_t convertedShort = ntohs(netShort);uint32_t convertedLong = ntohl(netLong);cout << "Converted short: " << hex << convertedShort << endl;cout << "Converted long: " << hex << convertedLong << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/882294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ORACLE 19C安装 RAC报错

1. 问题描述 在Oracle 19C RAC的安装过程中&#xff0c;使用克隆方式在两个节点上部署集群。当第一个节点配置好基础服务后&#xff0c;关机并克隆节点。当尝试在第二个节点上通过页面进行RAC安装时&#xff0c;出现以下错误&#xff1a; [INS-32070] Could not remove the n…

React01 开发环境搭建

React 开发环境搭建 一、创建 React 项目二、项目精简 一、创建 React 项目 执行下述命令创建 react 项目 blu-react-basis npx create-react-app blu-react-basis项目目录结构如下&#xff1a; 执行下述命令启动项目 npm run start启动效果如下&#xff1a; 二、项目精简 …

Vue3:同一项目同一浏览器只允许打开一个标签页

说明&#xff1a; 阻止同一浏览器打开多个项目标签页&#xff0c;防止多标签页重复时间统计累加&#xff0c;适用于基于微信公众号页面或指定浏览器的计时统计等项目活动&#xff0c;计时在线学习时间统计等。 效果&#xff1a; main.js import {createApp} from vue import…

【Linux系统编程】第三十四弹---使用匿名管道构建简易Linux进程池

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、引言 2、进程池的基本概念 3、管道在进程池中的应用 4、进程池的实现 4.1、master类定义 4.2、测试信道 4.3、通过cha…

OpenCV高级图形用户界面(12)用于更改指定窗口的大小函数resizeWindow()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::resizeWindow() 函数用于更改指定窗口的大小。这使得你可以根据需要调整窗口的宽度和高度。 注释 指定的窗口大小是指图像区域的大小。工具栏…

Linux 手撕线程池

前言 线程池 是 池化技术 中很典型的一个&#xff0c;它旨在高效的管理和复用线程资源&#xff01;在现在的计算机体系中&#xff0c;线程是执行任务&#xff08;调度&#xff09;的基本单位。然而&#xff0c;频繁的创建和销毁线程也会带来较大的开销&#xff0c;包括系统资源…

区块链开发入门: 原理、技术与实践

随着区块链技术的迅猛发展&#xff0c;它不仅改变了金融领域&#xff0c;还对供应链、医疗、身份认证等多个行业产生了深远影响。对于想要进入区块链开发领域的初学者而言&#xff0c;了解区块链的基本原理、相关技术以及实际应用场景至关重要。本文将为您提供一份全面的区块链…

网络变压器在PCIe网口应用的案例

PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;是一种高速串行计算机总线标准&#xff0c;用于连接计算机主板上的设备&#xff0c;如显卡、网络适配器、存储控制器等。H82422S 网络变压器&#xff08;Ethernet Transformer&#xff09;&#xff0c;在…

[Git]一文速通

概述 Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件(Java类、xml文件、html页面等, )在软件开发过程中被广泛使用 Git的作用 代码回溯版本切换多人协作远程备份 通过Git 仓库来存储和管理代码 文件&#xff0c;Git 仓库分为两种: 本地仓库: 开…

循序渐进丨在 MogDB 数据库中实现 Oracle ASH能力

我们都知道&#xff0c;当 Oracle 数据库出现性能故障后&#xff0c;一般会在线上实时诊断数据库性能问题&#xff0c;特别是资源突然打高的场景&#xff0c;这个时候用到ASH的数据&#xff0c;就能很大程度上准确定位问题所在。 Oracle ASH 在 Oracle 数据库中&#xff0c;实…

基于微博评论的自然语言处理情感分析

目录 一、项目概述 二、需要解决的问题 三、数据预处理 1、词汇表构建&#xff08;vocab_creat.py&#xff09; 2、数据集加载&#xff08;load_dataset.py&#xff09; 四、模型构建&#xff08;TextRNN.py&#xff09; 1、嵌入层&#xff08;Embedding Layer&#xff…

【学术会议论文投稿】ECMAScript标准:塑造现代Web开发的基石

https://www.ais.cn/attendees/index/MVNV3U 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 ECMAScript的历史背景与版本更新 ECMAScript的核心特性 1. 变量和数据类型 2. 变量声明 3. 运算符 4. 控制流语句 5. 函数 6. 错误处理 7. 模板…

github学生认证(Github Copilot)

今天想配置一下Github Copilot&#xff0c;认证学生可以免费使用一年&#xff0c;认证过程中因为各种原因折腾了好久&#xff0c;记录一下解决方法供大家参考。 p.s.本文章只针对Github学生认证部分遇到的问题及解决方法&#xff0c;不包括配置copilot的全部流程~ 1、准备工作…

构建后端为etcd的CoreDNS的容器集群(六)、编写自动维护域名记录的代码脚本

本文为系列测试文章&#xff0c;拟基于自签名证书认证的etcd容器来构建coredns域名解析系统。 一、前置文章 构建后端为etcd的CoreDNS的容器集群&#xff08;一&#xff09;、生成自签名证书 构建后端为etcd的CoreDNS的容器集群&#xff08;二&#xff09;、下载最新的etcd容…

Github 2024-10-19 Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2024-10-19统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Python项目2Dart项目1TypeScript项目1Vue项目1CUE项目1RustDesk: 用Rust编写的开源远程桌面软件 创建周期:1218 天开发语言:Rust, …

敏捷Scrum项目管理方法,如何做好敏捷项目管理❓

在当今快速变化的商业环境中&#xff0c;项目管理方法的选择对于项目的成功至关重要。敏捷Scrum作为一种轻量级、迭代式的项目管理方法&#xff0c;因其灵活性和高效性而备受推崇。作为项目经理&#xff0c;掌握敏捷Scrum项目管理方法不仅有助于提升项目交付效率&#xff0c;还…

2024年软件设计师中级(软考中级)详细笔记【7】面向对象技术(上)(分值10+)

目录 前言第7章 面向对象技术 &#xff08;上&#xff09;7.1 面向对象基础(3-4分&#xff09;7.1.1 面向对象的基本概念7.1.2 面向对象分析&#xff08;熟记&#xff09;7.1.3 面向对象设计7.1.4 面向对象程序设计7.1.5 面向对象测试 7.2 UML(3~4分)7.2.1 事务7.2.2 关系7.2.2…

Qt 支持打包成安卓

1. 打开维护Qt&#xff0c;双击MaintenanceTool.exe 2.登陆进去,默认是添加或移除组件&#xff0c;点击下一步&#xff0c; 勾选Android, 点击下一步 3.更新安装中 4.进度100%&#xff0c;完成安装&#xff0c;重启。 5.打开 Qt Creator&#xff0c;编辑-》Preferences... 6.进…

Windows下配置Nginx和PHP

之前在Windows开发php项目用的是phpstudy&#xff0c;好用的很。但是phpstudy好久没有更新了&#xff0c;感觉PHP像没有人再用了一样。但是PHP拿来开发小系统&#xff0c;还是很高效的&#xff0c;今天记录如何在Windows环境下配置Nginx和PHP。 1. 配置nginx Nginx软件下载解压…

【Python】selenium遇到“InvalidArgumentException”的解决方法

在使用try……except 的时候捕获到这个错误&#xff1a; InvalidArgumentException: invalid argument (Session info: chrome112.0.5614.0) 这个错误代表的是&#xff0c;当传入的参数不符合期望时&#xff0c;就会抛出这个异常&#xff1a; InvalidArgumentException: invali…