通过 websockets 以二进制形式发送数据将数字编码为文本

时间:2020-12-25 14:55:18

标签: javascript websocket iot

我正在做一个项目,我将通过 websocket 连接将二进制数据发送到 LED 矩阵。我想以字节数组的形式发送二进制数据,例如在矩阵上从右到左绘制一条对角线如下所示:

0b00000001
0b00000010
0b00000100
0b00001000
0b00010000
0b00100000
0b01000000
0b10000000

当我尝试这样做时遇到的问题是,当我尝试发送这些数据时,无论我使用什么 websocket 客户端测试器,这些数字都会被编码为字符串。

也就是说,当我尝试发送二进制数 1 时,套接字客户端发送的不是 0x01,而是十进制的 49/十六进制的 0x31这是字符串 '1' 在 ascii 或 unicode 中的字符代码。

enter image description here enter image description here

起初我认为这个问题出在驱动矩阵的代码中的 arduino 端,但后来我通过 websocket 服务器将其追溯到测试客户端。如果我弹出wireshark并查看从客户端到服务器的传输数据,编码发生在客户端,即websocket传输的第一部分。

wireshark analysis

我认为这可能是我使用 Firecamp 错了,但使用不同的客户端时会发生同样的事情,在这种情况下 websocat

websocat test

所以,我的问题是:通过 websockets 发送二进制数的正确方法是什么?我是否只是误解了二进制功能应该如何工作,就像我希望我将数字作为字符串发送并将它们转换回另一侧的数字?

1 个答案:

答案 0 :(得分:0)

因此,在阅读并思考之后,我发现了我的问题。 @myst 在上面的评论中也提到了它。

在上面的示例中,我在 websocat 命令的交互式提示中输入我想要的数字,我认为我输入的内容被接受为数字,因为数字是一个整数,我没有用引号将它括起来。事实证明,它仍然被识别为一个字符串(考虑到 cli 工具如何接受参数,事后看来是有道理的)。

在上面的例子中,我也尝试创建一个测试文件并在其中添加数字,再次认为它们会被接受为数字,但它们被作为字符串读入。

在进行故障排除时,我意识到如果我以另一种形式发送二进制文件,例如图像,我发送的图像文件不会作为文本读取,而是二进制文件。< /p>

即如果你cat myimage.png你不会得到一堆二进制数,你会得到空白和乱码。

cat-ing an image file

这不是乱码,只是你吐出一堆二进制代码,随着数字的出现,其中一些没有映射到字符编码(空格),然后它们中的一些确实匹配了一个字符编码,但它不是任何可读的顺序,所以它看起来像胡言乱语。

于是,我查找了如何手动创建一个简单的二进制文件,发现this super user post

<块引用>

您可以使用 printf 命令。

$ printf "\x08\x00\x00\x10" > file1
$ hexdump file1
00000000  08 00 00 10                                   |....|
00000004

有了这些知识,我创建了一个二进制文件,用从 1 到 8 的简单十六进制计数填充它,然后将其分类到 websocat 工具:

 printf "\x01\x02\x03\x04\x05\x06\x07\x08" > binfile \
> cat binfile | websocat -b ws://localhost:3002

这给出了预期的输出:

working!

实际上在写完这篇文章后,我回去尝试了没有 write -> cat 的文件,它也可以正常工作:

printf "\x01\x02\x03\x04\x05\x06\x07\x08" | websocat -b ws://localhost:3002

我不确定为什么这在 Firecamp 中不起作用,但我已经在与他们的工程师交谈并为他们寻找金丝雀版本,所以希望我们也能够在那里解决它。

所以我很高兴去。现在我必须回去重写一些代码:P

更多信息

我还花了一些时间与 Firecamp 的开发人员合作,结果证明他们的数组缓冲区和数组缓冲区视图消息类型确实发送了值与实际数字的 ascii 代码。他们已经纠正了这个问题(我在他们传递给我的金丝雀版本中确认了它)并且应该在 v2.0 中。