首页 > 编程语言 >c# 通信中字节序处理。

c# 通信中字节序处理。

时间:2023-07-13 19:31:50浏览次数:26  
标签:编码 字节 c# 程序 System 通信 数组


c# 通信中字节序处理。



最近在写一个短信下发功能,客户端使用c#和java的短信网关的进行网络通信。

之前使用java进行开发,一切正常,改用c#无法收到网关应答。

想了半天意识到是不是网络字节序问题,

java默认就是大端字节序,和网络字节序是一至的,所以不转换也不会有问题,

而c#在windows平台上是小端字节序。

网络发送字节流是按大端序发送,也就是从左到右发送,和c#的小端序相反,造成网关不能正常识别协议。

尝试c#中转换一下字节序,通信成功。

c#中字节序转换有两种方法。

非字串使用 System.BitConverter.GetBytes()方法,先读入字节数组中,然后再用Array.Reverse()对byte数组反序一下,得到大端序字节数组。

代码:

short x = 6;

byte[] a=System.BitConverter.GetBytes(x); //得到小端字节序数组

Array.Reverse(a); //反转数组转成大端。

 

 

另外c#直接提供了网络字节序转换方法。

System.Net.IPAddress.HostToNetworkOrder(本机到网络转换)

System.Net.IPAddress.NetworkToHostOrder(网络字节转成本机)

推荐使用这种方法,简单有效。

代码示例:

short x = 6;

short b = System.Net.IPAddress.HostToNetworkOrder(x); //把x转成相应的大端字节数

byte[] bb = System.BitConverter.GetBytes(b);//这样直接取到的就是大端字节序字节数组。

 

对于字符串型:使用 System.Text.Encoding.Default.GetBytes();直接取字串对应字节数组。

不知道为什么这个方法取到的直接就是大端字节数组。不用转换。

后来查了一下,关于字串的字节序问题,因为gbk和utf-8都是以单个字节表示数字的,所以不存在字节序问题,在多个不同系统架构都用。对于utf-16,则是以双字节表示一个整数,所以为会有字节序问题,分大小端unicode。

System.Text.Encoding.Default.GetBytes();在我的简体中文系统上是以gb2312的编码,也就是单个字来进行编码的,所以也不会有字节序问题。

补充:“对于任何字符编码,编码单元的顺序是由编码方案指定的,与endian无关。例如GBK的编码单元是字节,用两个字节表示一个汉字。这两个字节的顺序是固定的,不受CPU字节序的影响。UTF-16的编码单元是word(双字节),word之间的顺序是编码方案指定的,word内部的字节排列才会受到endian的影响。”,所以utf-8也没有字节序的问题。字节序问题之存在于需要使用两个字节以上来表示整数。而UTF-8只是一串字节流,不存在字节序问题,不过将这些字节流翻译成Unicode比其他的传输方式复杂。以字节为单位编码的,无论一个汉字是多少个字节,都无字节序问题。
你注意,字节序问题不是指多个字节传输的先后,这个是固定的无异议的。而是指一个多字节编码在机器中的表示方式问题。
char str[] = "abaksdkakskasklasflk";这个无字节序问题。

int str[] = {0x11223344, 2, 3 }就有字节序问题了。因为str[0]同样数值不同机器中表示不同。

而剩下的, 就是字符编码内部的字节序了。比如UTF-16是用两个字节表示一个字符,但是这两个字节内部如何排序,系统并不知道,所以必须指定字节序。但是UTF-8由于几个字节表示并不相同,一定要从那个表示长度的字节开始读,相当于一开始就知道该从哪里是队头队尾,所以不存在字节序问题。

附上字节序说明:

 

为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?尤其是当你把你在微机上运算的结果运用到计算机群上去的话。在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的 0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。

 

 用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示:

  Big Endian

  低地址 高地址

  ----------------------------------------->

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  | 12 | 34 | 56 | 78 |

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  Little Endian

  低地址 高地址

  ----------------------------------------->

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  | 78 | 56 | 34 | 12 |

  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

标签:编码,字节,c#,程序,System,通信,数组
From: https://blog.51cto.com/u_1044274/6715595

相关文章

  • Codeforces Round #882 (Div. 2) A-D
    比赛链接A代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;inta[107];intf[107];boolsolve(){intn,k;cin>>n>>k;for(inti=1;i<=n;i++)cin>>a[i];for(inti=1;i<=n-1;......
  • 【Spring Security】的RememberMe功能流程与源码详解
    相关课程前言今天我们来聊一下登陆页面中"记住我"这个看似简单实则复杂的小功能。如图就是某网站登陆时的"记住我"选项,在实际开发登陆接口以前,我一直认为这个"记住我"就是把我的用户名和密码保存到浏览器的cookie中,当下次登陆时浏览器会自动显示我的用户名和密码,就不用我再次......
  • 如何解决返回[object Promise]标准答案
    constmyPromise=newPromise((resolve,reject)=>{//执行异步操作//当操作完成时调用resolve()或reject()});myPromise.then(result=>{//在Promise被解析时执行的回调函数console.log(result);//输出Promise的值}).catch(error=>{//在Promise被拒绝时执......
  • 记一次CentOS7.7文件系统只读Read-only file system 并且/dev/只有一个设备文件 null
    环境VMwareWorkstationPro15.5操作系统CentOS7.7现象:处理方法1.单用户修复文件系统失败2.救援模式备份数据失败3.把不能正常启动的磁盘,挂载到正常启动虚拟机,扫描逻辑卷,激活,挂载(1)把有问题的磁盘挂载到正常启动的机器上选择需要修复的盘......
  • m基于FPGA的64QAM调制解调通信系统verilog实现,包含testbench,不包含载波同步
    1.算法仿真效果 本系统进行了两个平台的开发,分别是: Vivado2019.2 Quartusii18.0+ModelSim-Altera6.6d StarterEdition 其中Vivado2019.2仿真结果如下:     仿真结果导入matlab可以看星座图:  Quartusii18.0+ModelSim-Altera6.6d StarterEditi......
  • Groovy定义的Class在Spel中使用
    @ResourceprivateICustomFunctionServicecustomFunctionService;@PostConstructprivatevoidinit(){LambdaQueryWrapper<CustomFunctionEo>wrapper=Wrappers.lambdaQuery(CustomFunctionEo.class).eq(CustomFunctionE......
  • m完整的SC-FDE单载波频域均衡通信链路matlab仿真,包括UW序列,QPSK,定时同步,载波同步,
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要        完整的SC-FDE单载波频域均衡通信链路的设计和实现,包括UW序列的设计、QPSK调制、帧同步、定时同步、载波同步、SNR估计和MMSE信道估计等环节。本文首先介绍了SC-FDE通信系统的基本......
  • BatchNorm
    BatchNorm层【对数据进行归一化】位置:全连接层:仿射变换与激活函数之间卷积层:卷积层后与激活函数之前作用:①加快收敛速度;②防止梯度爆炸/梯度消失③防止过拟合......
  • Power APP Canvas组件简单控制画布控件
    效果图:图中绿色部分是组件,通过组件控制画布中按钮的点击事件。具体实现:1、组件按钮中赋值一个变量比如左按钮给yyy赋值false右按钮赋值true;2、增加输出属性                          将其赋值为此变量,此处用布尔......
  • Redis压测工具(redis-benchmark)
    redis性能测试工具可选参数如下所示:redis性能测试工具可选参数如下所示:序号选项描述默认值1-h指定服务器主机名127.0.0.12-p指定服务器端口63793-s指定服务器socket4-c指定并发连接数505-n指定请求数100006-d以字节的形式指定SE......