首页 > 其他分享 >彻底理解字节序

彻底理解字节序

时间:2024-09-07 16:02:31浏览次数:9  
标签:字节 彻底 unsigned 数值 发送 理解 内存 如上图

1.基本理论

  • 计算机发送数据从内存低地址开始.
  • 计算机接收数据的保存从低地址开始.

2.非数值型网络数据传输


如上图例子所示,发送端发送了四个字节内容,分别为0x12,0x34,0x56,0x78,假设这四个字节不表示数值例如unsigned int,而是图片内容数据。发送端从低内存地址开始发送四个字节,接收端将接收到的数据按照内存从低到高存储,这样完全没有问题,并不涉及字节序。

3.数值型数据存储


如上图所示,如果内存中的四个字节表示一个unsigned int类型整数,那么该整数值为多少呢?在不同类型计算机上可能表示数值不一样,0x12345678或者0x78563412.

如上图所示,如果计算机CPU架构是大端字节序:数值的高字节存储在内存的低位,则表示0x12345678;如果计算机CPU架构是小端字节序:数值的高字节存储在内存的高位,则表示0x78563412.如果传输的是数值型数据,网络传输层协议要求先发送数值的高字节,即低内存地址存储数值的高位,也就是大端字节序。平时常说的网络字节序就是大端字节序。另外,字节序只有在传输数值型数据时才会用到,所以网络开发中只有IP地址、端口等信息会需要字节序转化,其它数据并不需要。

4.字节序转换


下面我们着重讨论下传输数值型数据时的字节序转换。既然网络固定用大端字节序,那么发送端和接收端就要考虑到字节序转换问题。
如上图左侧所示,发送端如果是小端字节序,实际想要发送的是val=0x78563412,但是低内存是0x12,不满足网络传输层的要求"先发送数值的高位",经过htonl转换,生成新数newVal=0x12345678,实际发送newVal,满足传输层要求。
如上图右侧所示,发送端如果是大端字节序,实际想要发送的是val=0x12345678,低内存是0x12,满足网络传输层的要求"先发送数值的高位"。实际开发中不管当前是大端还是小端都会做转换,经过ntohl转化为网络字节序,生成新数newVal还是等于0x12345678。

如上图所示,接收端收到0x12,0x34,0x56,0x78后,不管本机是大端还是小端字节序,经过htonl转换得到0x12345678这个值,即将低内存的0x12作为数值的高字节.

5.转换代码

 htonl和ntohl实现原理一样,都是将低内存的内容作为数值的高字节,将高内存的内容作为数值的低字节,形成一个数值。
   unsigned int myhtonl(const unsigned int val)
  {
  unsigned char tempCh[4]={0};
  memcpy(tempCh,&val,sizeof(val));
  unsigned int res=0;
  res = (((unsigned int)tempCh[0])<<24) | (((unsigned int)tempCh[1])<<16) | (((unsigned int)tempCh[2])<<8) | ((unsigned   int)tempCh[3]);
  return res;
  }

标签:字节,彻底,unsigned,数值,发送,理解,内存,如上图
From: https://www.cnblogs.com/madadam/p/18401804

相关文章

  • 字节跳动笔试题:自动校对程序:解决王大锤的拼写错误
    字节跳动面试题:自动校对程序:解决王大锤的拼写错误引言问题描述数据范围输入输出描述算法与数据结构伪代码C代码实现代码解释测试用例边界情况复杂度分析结论后记引言王大锤,一个出版社的编辑,每天面对海量的英文稿件,不胜其烦。然而,凭借他蓝翔技校挖掘机......
  • 如何理解cuda 中的__launch_bounds__?
    __launch_bounds__ 是CUDA编程中的一个修饰符,用于优化GPU内核的执行。它帮助编译器在生成代码时考虑线程块的配置,以提高执行效率。理解 __launch_bounds__ 有助于你更好地控制内核的性能,尤其是在处理大型数据集或复杂计算时。__launch_bounds__ 的作用优化内核执行:_......
  • 理解 TON 智能合约中的 receive 函数与 fun 函数的区别
    在TON(TheOpenNetwork)智能合约开发中,函数是实现合约逻辑的关键组成部分。开发者通常会使用fun函数来编写业务逻辑,但当涉及到与外部消息的交互时,就需要用到receive开头的特殊函数。那么,receive函数和fun函数有什么区别?为什么不能用fun函数代替receive函数?本文将深......
  • 掌握Linux磁盘管理:理解fdisk, lsblk, mount及resize2fs命令
    作为Linux系统运维人员,日常工作中经常需要处理磁盘管理和文件系统调整的任务。这些任务包括但不限于查看磁盘分区、识别挂载点、以及调整文件系统大小等。今天,我们将通过几个常用的命令——fdisk、lsblk、mount,以及一个需要注意的命令resize2fs——来探讨如何在Linux环境下进行这......
  • 从底层代码理解Vue 响应式系统的核心机制
    在Vue.js的响应式系统中,依赖收集和变化检测是核心机制,确保了数据的变动能够自动驱动视图更新。在上文我们已经了解了的依赖收集和变化检测与更新过程,主要依赖于Watcher、Dep和响应式的getter和setter来实现。下面详细从底层代码解释这两个过程文章目录1.依赖收......
  • 深入理解synchronized的原理是什么
    对象头锁机制原则Synchronized的原理是什么  Synchronized是由JVM实现的一种实现互斥同步的实现方式。如果查看synchronized关键字修饰的字节码,会发现在编译器生成了monitorenter和monitorexit两个字节码指令。  这两个指令的意思就是在虚拟机执行到monitorenter......
  • 深入理解动态内存(一):动态内存使用常见问题
    目录对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放⼀块动态开辟内存的⼀部分对同⼀块动态内存多次释放动态开辟内存忘记释放(内存泄漏)对NULL指针的解引用操作#include<stdio.h>#include<stdlib.h>intmain(){ int*p......
  • 对深度学习概念的基础理解与认识
    一、神经网络的组成人工神经网络(ArtificialNeuralNetworks,简写为ANNs)是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的,并具有自学习和自适应的能力。神经网络类型......
  • Android 开发避坑经验(2):深入理解Fragment与Activity交互
    在Android开发过程中,Fragment和Activity之间的交互是一个常见的难题,处理不当会引发UI更新问题、生命周期混乱、数据丢失等问题。这篇文章将深入探讨如何避免这些常见坑点,提供可靠的解决方案,并通过示例代码展示最佳实践。1.坑点:Fragment和Activity的生命周期差异......
  • 网络编程day02(字节序、TCP编程)
    目录【1】字节序1》大小端转换2》端口转换  3》IP地址转换主机字节序转换为网络字节序(小端序->大端序)网络字节序转换为主机字节序(大端序->小端序) 【2】TCP编程1》流程2》函数接口1> socket2>bind3>listen4>accept 5>recv 6>connect7>send 3》代......