`
vanadiumlin
  • 浏览: 493207 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

c# 通信中字节序处理。

 
阅读更多

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# 串口通信(彻底解决C#串口通信中的数据丢失问题)

    以网上某位大虾的源码为版本,沿用了其可用的代码部分。对其余欠妥部分进行了改造。不要资源分,是大家不用为积分而烦恼。出来混都不容易,希望大家相互照应!

    c# Sockets实现客户端和服务端通信

    c# Sockets实现客户端和服务端通信 例如客户登录 发消息,服务器返回消息

    C#使用SerialPort类实现串口通信

    最近在学C#,在网上找了很多有关串口通信的资料,自己总结了一下,开发环境是VS2005,代码实现

    C# 将图片文件转换成字节流存储在TXT

    本代码实现将JPG等图片文件转换为字节流并存储在TXT中,方便通信传输时将图片文件存储在数组中

    C#TCP 通信(TCP发送16进制)

    C#TCP 通信(TCP发送16进制)

    C#结构体和C++字节数组的转换

    在写C#TCP通信程序时,发送数据时,只能发送byte数组,处理起来比较麻烦不说,如果是和VC6.0等写的程序通信的话,很多的都是传送结构体,在VC6.0中可以很方便的把一个char[]数组转换为一个结构体,而在C#却不能直接...

    C#与C++通讯字节流转换结构体

    C#实现与C++程序通信,将字节流转换为结构体。

    用于将Modbus通信中截取后四字节的十六进制数转换为单精度浮点数(源码)

    用于将Modbus通信中感应器返回的数据截取后的数据处理成浮点数,目前只弄了四字节的十六进制数转换为单精度浮点数。

    C#实现两台PC机间TCP通信

    C#实现在VS下两台PC机间的TCP通信,采用Windows窗体应用,UI界面接收信息和使用按钮操作。 包含服务器和客户端,运用多线程进行TCP通信,操作简单,适合初学者学习TCP本机间局域网下的通信。

    c#上位机串口通信助手源代码

    非常适合初学者研究,功能齐全、智能好用,具体功能如下: ...2 软件打开时,自动复原到上次关闭时的状态 3 不必关闭串口,即可直接进行更改初始化设置内容(串...欢迎对c#有兴趣的爱好者们,加入c#技术交流群(33647125)

    C# 与西门子PLC进行OPC通信实例源码.zip

    【程序老媛出品,必属精品,亲测校正,质量...源码说明: 基于C#编写的西门子PLC OPC网络通信示例代码,建立了group,追加了item,自定义读写地址,可以批量读写多个字节数据。 适合人群:新手及有一定经验的开发人员

    C#中结构体定义并转换字节数组详解

    最近的项目在做socket通信报文解析的时候,用到了结构体与字节数组的转换;由于客户端采用C++开发,服务端采用C#开发,所以双方必须保证各自定义结构体成员类型和长度一致才能保证报文解析的正确性,这一点非常重要...

    C#通信调试工具1.0(带源码).zip

    1.串口,TCP服务端/客户端,UDP服务端/客户端通讯调试 2.支持Hex,ASCII,UTF8,GB2312编码调试 ...4.字节计算器/检验值计算器(CRC16,自定义多项式CRC16,XOR) 5.串口超级终端 6.Socket通信监视器 7:Ping调试

    使用C#的高扩展性硬件通信平台_C#_代码_下载

    字节序问题修复(完成) TaskManager 中的命名模式(完成) 版本 1.2.4 OPC UA 支持(完成) 标签的 OPC 正则表达式比较器(完整) 版本 1.3.0 .NET Core 支持(完成) 修复 BaseMachine 中的错误(完成) 更多详情...

    c#实现HidUsb设备通信

    //处理接收到的数据逻辑 } //第五步:向Hid设备发送数据"0xa0 00 0x12 0x9 0x22" string txt = "0xa0 00 0x12 0x9 0x22"; //把数据转换为字节数组 byte[] data = ConvertHelper.StringToByte(txt2); byte bt = 0;...

    C#超级通信调试工具源码

    4.字节计算器/检验值计算器(CRC16,自定义多项式CRC16,XOR) 5.串口超级终端 6.Socket通信监视器 7:Ping调试 --------------------- 作者:知秋物联 来源:CSDN 原文:...

    模块通信距离测试小工具 串口通信C#

    为了解决在测试模块通信距离中出现的误差大,每个人的测试条件都不一样,没有标准, 没有数据(数据最能说明问题),数据手动记录容易丢失,手动计算的误差大等情况.在经理的 指导下,特此开发了一款自动测试模块...

    C#超级通信调试工具源码20130916

    C#超级通信调试工具源码 源码描述: 软件名称:C#超级通信调试工具 功能概要: 1.串口,TCP服务端/客户端,UDP服务端/客户端通讯调试 2.支持Hex,ASCII,UTF8,GB2312编码调试 3.接收数据可通过右键菜单一键计算Hex...

    C#通过TCP读写S7-200 SMART PLC地址

    通过C#读写 S7-200 SMART PLC 文档中的代码全部通过实物测试确认可以 读写参数。只需要按文档中的步骤即可 读写参数

Global site tag (gtag.js) - Google Analytics