【问题标题】:Read socket data Hex instead of Ascii读取套接字数据 Hex 而不是 Ascii
【发布时间】:2021-12-14 02:44:03
【问题描述】:

我每 5 秒从一台数控机床接收数据。数据长度为 66 字节。根据我的指南,每两个字节都有特殊的含义。设备通过套接字将数据发送到特定的 IP 和端口。有人告诉我应该将数据读取为十六进制而不是 ascii。

这行代码返回

        string data = Encoding.ASCII.GetString(data.buffer,0,66);

这个;

"\0\u0004\0\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\r\0\r\0\0\0\0\0\0:a\u0002@\0?\0`\u001b?\u0015U\0\0\0\0\u0001\u0010\0\u0018\0\0\u000f\a\0\0\0\0\0\0\0\0\0\0\0\0\0\0u/"

当然对我没用。

我确实尝试使用该代码将字节数组转换为十六进制字符串;

  StringBuilder sb = new StringBuilder();
                foreach (byte b in buffer)
                    sb.Append(b.ToString("X2"));

                string hexString = sb.ToString();

得到的结果为

00040001000000000000000000020000000000000000000000003A9D023F00A000601B841555000000000110001800000F070000000000000000000000000000752F

当我尝试将此结果转换为字符串时,没有成功,没有任何意义。

目标

我想要实现的是,将传入的套接字数据读取为十六进制,并使用每两个字节作为一个单词来匹配一个值。例如,前 2 个字节应该匹配 0 或 1。我有它返回吗? (问号)

谢谢。

【问题讨论】:

  • 您收到的数据有什么问题。您收到了 66 个字节。该字符串 ("00040001...") 是 132 个十六进制字符(即 66 个字节)。看起来它可能是正确的(前 16 位可能是 short 4,下一个是 short 1。最后两个字节(就在所有这些零之后)看起来像校验和。我们没有不知道你的 NC 机器的数据应该是什么样子,但这看起来远非垃圾。“将此结果转换为字符串”是什么意思 - 它已经是一个字符串?
  • 听起来 cnc 机器可能正在发送一个实际的十六进制编码字符串,其中每 2 个十六进制字符代表 1 个字节的数据。如果是这种情况,那么这是How can I convert a hex string to a byte array? 的副本。如果您能显示您收到的实际数据,并引用您正在使用的编程指南的实际文本,将会有所帮助。
  • 作为测试,获取您的代码并让它运行,因此它每 5 秒接收一个新数据包。将数据格式化为您显示的 132 位十六进制字符串,并将其写入控制台(或文件,或...)。您应该看到相同格式的数据,并且可能非常相似的数据 - 可能每个数据包都会增加一个数字(我在这里猜测)。每次发生任何变化时,最后四位数字都可能发生很大变化。如果这就是您所看到的,那么您可能做对了。

标签: c# sockets hex


【解决方案1】:

有人告诉我应该以十六进制而不是 ascii 格式读取数据

我的直觉是这句话被错误引用或误解了。将二进制数据处理为字符串十六进制表示没有任何价值,就像将其转换为 ascii 没有任何价值......处理二进制数据的唯一合理方法是二进制,除非你有一种有意义的方式来转换它。

您提到您需要单词(2 字节)分组,您可以根据需要将其转换为短数组或 ushort

var bytes = new byte[66];

var shortArray = new short[bytes.Length / 2];
Buffer.BlockCopy(bytes, 0, shortArray, 0, bytes.Length);

for (int i = 0; i < shortArray.Length; i++)
   shortArray[i] = BitConverter.ToInt16(bytes[(i*2)..(i*2+2)]);

免责声明:这只是一个例子,非常小心endianess 您的数据,还有其他方法可以做到这一点

【讨论】:

  • 我和其他开发人员之间很可能存在误解,但这是我得到的指示。他还说,转换为字符串时的前两个字节可以是 1 或 0,这意味着设备处于打开或关闭状态。我什至无法到达那里:/顺便说一句。感谢您的帮助。
  • 我完全明白你的代码的意思。从你的例子; shortArray[1] 可以是 1 或 0,但我得到 256。就像你说的没有正确解释,这就像追尾。再次感谢您。
  • 如何得到 256。十六进制字符串以 "00040001" 开头。 16 位 short 中有四个十六进制字符。根据endian-ness,这很容易是4,后跟1。当您处理此类数据时,您需要完整描述数据的含义(字节序、数据长度(这样的数据包有几个短裤、几个字节和一个 32 -位数量或两个挤在一起))。否则,你在猜测。但是,正如我上面提到的,它看起来不像垃圾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2020-11-29
相关资源
最近更新 更多