网络编程中的主机字节序与网络字节序

__builtin_xxx指令学习【5】__builtin_bswap16/32/64 __builtin_bswap16/32/64是GCC和Clang编译器提供的内置函数,用于交换一个整数的字节顺序。其中,__builtin_bswap16用于交换一个16位整数的字节顺序,__builtin_bswap32用于交换一个32位整数的字节顺序,__builtin_bswap64用于交换一个64位整数的字节顺序。这些函数的使用背景是在一些网络编程和底层编程中,需要对字节序进行处理和转换,而交换字节顺序是一个常见的操作 阅读详情

一、大端、小端
"大端"和"小端"表示多字节值的哪一端存储在该值的起始地址处;小端存储在起始地址处,即是小端字节序;大端存储在起始地址处,即是大端字节序;
或者说:
1.小端法(Little-Endian)就是低位字节排放在内存的低地址端(即该值的起始地址),高位字节排放在内存的高地址端;
2.大端法(Big-Endian)就是高位字节排放在内存的低地址端(即该值的起始地址),低位字节排放在内存的高地址端;
举个简单的例子,对于整型数据0x12345678,它在大端法和小端法的系统中,各自的存放方式如下图1所示:


二、网络字节序
网络上传输的数据都是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字节还是低位字节处理,是一个比较有意义的问题;
UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节(即:高位字节存放在低地址处);由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的;
所以说,网络字节序是大端字节序;
比如,我们经过网络发送整型数值0x12345678时,在80X86平台中,它是以小端发存放的,在发送之前需要使用系统提供的字节序转换函数htonl()将其转换成大端法存放的数值;
如下图2所示:
一般华为规定再进行网络传输的时候,不管主机端是什么,都转换一下,这个也是对的。因为一般网络协议的实现中都会对htonl等的实现有所明确,if系统是大端,那么htonl(a)=a;else htonl(a)进行字节转换。看一个例子:
linux内核源码里就有如此处理。
/usr/include/netinet/in.h中
#include <endian.h>
/* Get machine dependent optimized versions of byte swapping functions.  */
#include <bits/byteswap.h>
#ifdef __OPTIMIZE__
/* We can optimize calls to the conversion functions.  Either nothing has
   to be done or we are using directly the byte-swapping functions which
   often can be inlined.  */
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
   so these functions are all just identity.  */
# define ntohl(x) (x)
# define ntohs(x) (x)
# define htonl(x) (x)
# define htons(x) (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
#   define ntohl(x) __bswap_32 (x)
#   define ntohs(x) __bswap_16 (x)
#   define htonl(x) __bswap_32 (x)
#   define htons(x) __bswap_16 (x)
#  endif
# endif
#endif
也就是说如果是大端CPU,那么不用变,如果是小端CPU,就交换。
但是在我近期研究的工业以太网协议里面,SOEM的作者定义的标准却跟这个公认的TCP/IP网络标准是反的,下面的例子是在其中一个头文件中的定义:
#define LITTLE_ENDIAN
...
...
#if !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
  #define htoes(A) (A)
  #define htoel(A) (A)
  #define etohs(A) (A)
  #define etohl(A) (A)
 #elif !defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
  #define htoes(A) ((((uint16)(A) & 0xff00) >> 8) | /
                    (((uint16)(A) & 0x00ff) << 8))
  #define htoel(A) ((((uint32)(A) & 0xff000000) >> 24) | /
                    (((uint32)(A) & 0x00ff0000) >> 8)  | /
                    (((uint32)(A) & 0x0000ff00) << 8)  | /
                    (((uint32)(A) & 0x000000ff) << 24))
  #define etohs  htoes
  #define etohl  htoel
#endif
so,不管怎么样,只要理解了这个关系就可以,以不变应万变。
下面我们测试一下。
 三、字节序测试
不同CPU平台上字节序通常也不一样,下面这个简单的代码可以测试不同平台上的字节序:
#include <stdio.h>
#include <netinet/in.h>
int main(int argc,char** argv)
{
  int num = 0x12345678;
  unsigned char* pc = (unsigned char*)(&num);
  printf("local order:/n");
  printf("[0]: 0x%X addr:%u/n", pc[0], &pc[0]);
  printf("[1]: 0x%X addr:%u/n", pc[1], &pc[1]);
  printf("[2]: 0x%X addr:%u/n", pc[2], &pc[2]);
  printf("[3]: 0x%X addr:%u/n", pc[3], &pc[3]);
  num = htonl(num);
  printf("htonl order:/n");
  printf("[0]: 0x%X addr:%u/n", *pc, &pc[0]);
  printf("[1]: 0x%X addr:%u/n", *(pc+1), &pc[1]);
  printf("[2]: 0x%X addr:%u/n", *(pc+2), &pc[2]);
  printf("[3]: 0x%X addr:%u/n", *(pc+3), &pc[3]);
  return 0;
}
SPARC和PowerPC平台上的输出:
local order:
[0]: 0x12 addr:4290770212 //高位字节存放在低地址处,则是大端法;
[1]: 0x34 addr:4290770213
[2]: 0x56 addr:4290770214
[3]: 0x78 addr:4290770215 //低位字节存放在高地址处;
htonl order:
[0]: 0x12 addr:4290770212 //由此看出,主机字节序与网络字节一样;
[1]: 0x34 addr:4290770213
[2]: 0x56 addr:4290770214
[3]: 0x78 addr:4290770215
Intel X86平台上的输出:
local order:
[0]: 0x78 addr:4289157020 //低位字节存放在低地址处,则是小端法;
[1]: 0x56 addr:4289157021
[2]: 0x34 addr:4289157022
[3]: 0x12 addr:4289157023 //高位字节存放在高地址处;
htonl order:
[0]: 0x12 addr:4289157020 //由此看出,主机字节序与网络字节不一样;
[1]: 0x34 addr:4289157021
[2]: 0x56 addr:4289157022
[3]: 0x78 addr:4289157023
SQL 通过sum() over(order by ,rownum)实现财务现金日记账实例 SELECT 类型,to_char(发生日期,'yyyy-MM-dd') 发生日期,期初余额,借方金额,贷方金额, (CASE WHEN 借方金额>0 THEN '借' WHEN 贷方金额>0 THEN '贷' ELSE '平' END) 方向, sum(收支金额) over(order by 发生日期, rownum) 余额 FROM( SELECT LX 类型,账户,账号,摘要,发生日期,单据ID, ... 阅读详情

相关推荐

五分钟搞懂游戏开发中的抗锯齿算法

常见抗锯齿算法总结锯齿由来抗锯齿算法SSAAMSAACSAA 锯齿由来 场景的定义在三维空间中是连续的,而最终显示的像素则是一个离散的二维数组,这是计算机屏幕产生锯齿的原因。在计算机处理图形的过程中(渲染管线了解一下),有一个非常重要的阶段,就是光栅化,光栅化主要的作用是将顶点数据的不连续性通过插值计算,将两个顶点之间不存在的点进行弥补,然后实现到屏幕像素点上的一一映射。如图,现在要在屏幕上绘制一...

绿洲守望者 1万+

ntohs和htons区别?

一直以来都对这个两个函数含含糊糊的,今天又用到所以特意查看linux的源代码(/include/netinet/in.h) # if __BYTE_ORDER == __BIG_ENDIAN /* The host byte order is the same as network byte order,    so these functions are all just identity

hanchaoman的专栏 6200

【NLP】文献翻译4——CH-SIMS:中文多模态情感分析数据集与细粒度的模态注释

CH-SIMS: A Chinese Multimodal Sentiment Analysis Dataset with Fine-grained Annotations of Modality摘要1. 介绍2. 相关工作2.1 多模态数据集2.2 多模态情感分析2.3 多任务学习3. CH-SIMS 数据集3.1 数据获取3.2 标注3.3 特征提取4. 多模式多任务学习框架4.1 单模态子网4.2 特征融合网络4.3 优化目标5. 实验5.1 基准5.2 实验的细节5.3 结果和讨论5.3.1 与

YoungSeng's Blog 1万+

Linux网络编程 之 大小端初探

首先解释一下大小端的概念。大端(Big Endian),同时也是网络序,是数据在网络上传输的一种数据组织格式,其存储的方式比较符合人们读写的习惯。小端(Little Endian),这里不能说其是主机序,因为主机可能采用的是大端cpu也可能采用的是小端cpu,小端与大端相对。通过一个例子深入了解它们之间的区别:用一台Big Endian 和 另一台 Litt...

fantasydreams的专栏 2115

京东联盟h5st(3.1)加密参数逆向实战与反爬对抗策略

本文详细解析了京东联盟h5st(3.1)加密参数的逆向分析与实战破解过程。通过接口分析定位关键加密函数,拆解h5st结构并还原其基于SHA256和HMAC-SHA256的加密逻辑,最终使用Python集成JavaScript环境成功复现加密算法,并分享了应对反爬的频率限制、IP封禁及算法升级等对抗策略。

weixin_29246195的博客 1738

单细胞分析R包monocle3服务器安装教程

由于centos7系统yum只能安装到低版本gdal,而monocle3依赖包需要 gdal>2 版本,从gdal官网下载2.4.4版本编译安装。monocle3的安装是通过cole-trapnell-lab安装的,该包挂在github上,需要通过github先安装leidenbase包,需要提前安装devtools包下载工具。接着利用BiocManager安装相应的依赖包,由于这些包的特殊性,所以不要切换到国内Bio_Mirror镜像,否则会找不到,如果一次不成功,缺啥补啥即可。运行 ldconfig。

qq_36608036的博客 1万+

大尾端小尾端

中国科学技术大学 龙柏(C/C++学生) 2057

手把手教你学Simulink——基于Simulink的变换器老化预测与数字孪生(Digital Twin)

这不仅是技术的演进,更是从“事后救火”到“事前预言”的降维打击。:通过本文的实战演练,你不仅掌握了功率变换器“电气-热-老化”多物理场耦合的建模哲学,更深刻领悟了如何将高深的随机过程(粒子滤波)降维成可落地、可量产的工程工具;:起初,由于数据量少,粒子滤波器预测的剩余寿命(RUL)置信区间(95%)非常宽泛(如 1000~2000小时)。在工业4.0与智能制造的浪潮下,功率变换器(如光伏逆变器、车载OBC、服务器电源)不再是孤立的硬件,而是具备“自我感知”与“寿命预知”的智能节点。

MHD0815的博客 297

C语言内建函数:__builtin_XXX

首先内建函数有的属于预编译,有的属于运行过程的函数,这一点我现在还不是很清楚,待以后进一步详细讨论。 然后我们给出一个长代码,里面包含了常用的C语言内建函数,参考文章见文末。 总览: __builtin_ffs(s); __builtin_popcount(s); __builtin_ctz(s); __builtin_clz(s); __builtin_parity(i); ...

RToax 6454

学Simulink——基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计仿真

本文介绍了一种基于扩展卡尔曼滤波(EKF)的列车牵引电机转子温度在线估计方法,通过Simulink建模实现。文章首先阐述了EKF在估计电机转子温度中的优势,即利用易测量信号(如电流、电压、转速)在线估计难以直接测量的转子温度,并分析了温升对电机性能的影响。随后详细讲解了电机热电增广模型的构建,包括定子电阻温度关系、一阶热近似模型和PMSM的dq轴方程。接着,文章提供了Simulink建模的详细步骤,包括PMSM+FOC电流环的搭建、EKF算法的实现(推荐使用ExtendedKalmanFilter块或MAT

xiaoheshang_123的博客 56

基于R-CNN深度学习的生活垃圾检测与分类系统:数据集、模型和UI界面的完整实现

我们将使用一个公开的垃圾分类数据集来训练我们的模型。一个常见的数据集是TACO数据集(Trash Annotations in Context),该数据集包含多种垃圾类别,适用于垃圾分类任务。TACO数据集中的图像标注了垃圾的类别以及其在图像中的位置,适合用于目标检测任务。图片数据:每张图片中包含不同种类的垃圾。标签文件:每个图像有相应的标签文件,标注了图像中垃圾的类别、位置(通常为边界框坐标)等信息。dataset/images/image1.jpgimage2.jpg......其中,

YOLO 1101

网络编程--网络字节序和主机字节序详解

转自:https://blog.youkuaiyun.com/msdnwolaile/article/details/50727653 空中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其它平台产品的互通,在程序中发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字 节序转换为主机字节序。网络程序开发时 或是跨平台开发时 应该注意保证只用一种字节序 不然两方的解释不一样就会产生b...

qq_40443457的博客 5023

使用静态库在嵌入式系统中进行开发

静态库是一种包含预编译对象代码的文件,它可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。静态库是包含预编译对象代码的文件,可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。的静态库文件,可以在嵌入式系统的应用程序中使用它了。

ZrElixir的博客 203

Python网络编程之数据的主机字节序与网络字节序

数据的主机字节序指的是在高位内存保存数据的高位,在低位内存保存数据的低位。在Python中套接字实现服务端和客户端3-1_棉猴的博客-优快云博客中提到服务端监听的端口号是12345,代码为十进制的12345转换为十六进制是0x00003039,其在内存中的格式如图1①所示。图1 主机字节序与网络字节序从图1①中可以看到,左侧是内存低位,右侧为内存高位。这种把数据低位保存到内存低位,数据高位保存到内存高位的方式又叫“小头”(little-endian)。

hou09tian的博客 703

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Linux 网络编程:深度理解网络字节序与主机字节序、大端字节序与小端字节序

1.1什么是字节序在网络编程中,特别是在跨平台和网络通信时,字节序(Byte Order)是非常重要的概念。字节序指的是多字节数据在内存中的存储顺序。对于单字节数据(如char),不需要考虑字节序。但是对于多字节数据(如intshort),不同架构的 CPU 在内存中存放它们的顺序是不同的。高位字节放在前面还是后面?这就好比我们写日期:中国人习惯:年-月-日(2023-12-20)→高位在前美国人习惯:月-日-年(12-20-2023)→低位在前1.2 大端字节序主机字节序其本质是。

buyutang_的博客 966

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

网络编程(三)网络字节序与主机字节序、通信程序模板

不同的CPU设计时采用的字节序是不同的,谈到字节序的问题,必然牵涉到两大CPU派系。PowerPC系列采用大端字节序(big endian)方式存储数据,而x86与x86_64系列则采用小端字节序(little endian)方式存储数据。在Linux网络编程中,经常碰到网络字节序与主机字节序的相互转换。(1)小端字节序(Little endinan),数值低位存储在内存的低地址,高位存储在内存的高地址;(2)大端字节序(Big endian),数值高位存储在内存的低地址,低位存储在内存的高地址。

qq_45488834的博客 1107

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

python3 网络编程 主机字节序 网络字节序 相互转换

编写底层低层网络应用时,或许需要处理通过电缆在两台设备之间传送的低层数据。在这种操作中,需要把主机操作系统发出的数据转换成网络格式,或者做逆向转换,因为这两种数据的表示方式不一样。 1. 代码 # 主机字节序和网络字节序之间的相互转换 import socket def convert_integer(): data = 1234 # 32-bit print(...

whatday的专栏 914

Linux网络编程笔记 - 03 UDP - 主机字节序转换网络字节序函数

只要数据大于2个字节,发数据时一定要转成大端。 htons:一般用于转换端口号,short,2字节 htonl:一般用于转换ip,long,4字节 ntohl:将网络大端数据转换成主机可以识别的顺序,long = 4字节 ntohs:将网络大端数据转换成主机可以识别的顺序,short= 2字节 book@100ask:~/linux/network/2.UDP$ cat htonl.c #include <stdio.h> #include <arpa/inet.h&g...

我思故我在! 816

Linux C网络编程 大端与小端/网络字节序与主机字节序

网络字节序与主机字节序的概念 字节序分为主机字节序和网络字节序,主机字节序又称小端字节序,是低字节存放在地地址,而网络字节序又称大端字节序,是低字节放在高地址。当数据在不同的机器上传播时,就需要统一字节顺序以保证不出现错误。在发送数据前,先将需要转变的数据转成网络字节序再发送,接收时先转成主机字节序再处理,要特别注意的是,即使是本机的两个进程通信,也要考虑字节序的问题,比如JAVA的虚拟机就使用...

wwxy1995的博客 471

C++ 网络编程1 inet_addr,htons,inet_ntoa,ntohs,getpeername,主机字节序和网络字节序,大端,小端

1.inet_addr inet_addr是一个计算机函数,功能是将一个点分十进制的IP转换成一个长整数型数(u_long类型)等同于inet_addr()。 inet_addr方法可以转化字符串,主要用来将一个十进制的数转化为二进制的数,用途多于ipv4的IP转化。 SOCKADDR_IN server; server.sin_addr.S_un.S_addr = inet_addr...

qq_24127015的博客 1887

Python网络编程——主机字节序和网络字节序之间的相互转换

If you ever need to write a low-level network application, it may be necessary to handle the low-level data transmission over the wire between two machines. This operation requires some sort of conver...

weixin_34234721的博客 140

Linux网络编程:主机字节序 与 网络字节序

网络字节序 与 主机字节序 文章目录网络字节序 与 主机字节序前言字节序转化1.主机字节序 ——> 网络字节序2.网络字节序 ——> 主机字节序域名转换IP地址 前言 首先需要理解 大端模式 与 小端模式这两个点: 这两种模式代表着数据在内存中是如何存放的,我们直到,一个字节能够存放8位,如果是超过8位的数据该怎样存放呢? 如需要存放数据 0x12345678 大端模式存放:0x12345678 小端模式存放: 0x78563412 不难看出,大端模式也就是高位优先存放,小端模式也就是低位

Worthy_Wang的博客 650

Linux网络编程 | socket介绍、网络字节序与主机字节序概念与两者的转换、TCP/UDP 连接中常用的 socket 接口

文章目录套接字sockaddr 和 sockaddr_in 套接字 为什么要用到套接字? 我们知道,数据链路层、网络层、传输层协议是在内核中实现的。而 socket 就是 操作系统 提供给 应用程序 通过 系统调用 访问这些 协议服务 的一组 API 。socket 不但可以访问内核中 TCP/IP 协议栈,而且访问其他网络协议栈。 socket 定义的 API 提供哪些功能? 将 应用程序数据 从 用户缓冲区 中复制到 TCP/UDP 内核发送缓冲区 ,将发送数据交付内核。 从 TCP/UDP

Jormungand_V的博客 793

c++网络编程——解析主机字节序、网络字节序以及深入剖析tcp编程中万恶的结构体(爆肝)

本文介绍了网络编程中涉及的主机字节序、网络字节序以及相关结构体的核心概念。主要内容包括: 字节序详解: 大端序(高位在前)和小端序(低位在前)的区别 网络字节序统一采用大端序,保证跨平台通信 提供了htons/htonl/ntohs/ntohl四个转换函数 关键结构体: sockaddr通用地址结构体 sockaddr_in(IPv4专用)结构体及其字段说明 两者内存布局相同,可通过强制类型转换互用 IP地址转换方法: gethostbyname()支持域名解析 inet_addr()/inet_aton(

qizhiburce的博客 285

网络编程:写一个简单的网络通讯模型之前应该知道( socket函数 主机字节序和网络字节序 相关函数参数用到的结构体解读)

PF_INET IPv4 互联网协议族。PF_INET6 IPv6 互联网协议族。PF_LOCAL 本地通信的协议族。PF_PACKET 内核底层的协议族。PF_IPX IPX Novell 协议族。IPv6 尚未普及,其它的不常用,主要是IPv4。

2301_76320385的博客 1477

网络编程--字节序--主机字节序与网络字节序介绍及转换

一、字节序字节序:是指整数在内存中保存的顺序。字节序有两种实现方式:小端字节序(little endian):低字节数据存放在内存低地址处,高字节数据存放在内存高地址处。大端字节序(bigendian):高字节数据存放在低地址处,低字节数据存放在高地址处。如图所示:大字节序更符合我们的阅读习惯。但是我们的主机使用的是哪种字节序取决于CPU,不同的CPU型号有不同的选择。那么如何确定我们主机使用的哪...

stalin_的博客 7281
上一篇: 5分钟搞定字节对齐问题
下一篇: 函数指针数组的妙用
eric802
博客等级 码龄17年 24粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值