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

Sending data as binary via websockets encodes numbers as text

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

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

我 运行 在尝试执行此操作时遇到的问题是,当我尝试发送此数据时,无论我使用何种 websocket 客户端测试器,数字都会被编码为字符串。

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

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

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

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

所以在做了一些阅读和思考之后,我找到了我的问题。 @myst 在上面的评论中也提到了它。

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

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

当我进行故障排除时,我意识到如果我以另一种形式发送二进制文件,比如图像,我发送的图像文件不会以文本形式读入,它会是,你知道的,二进制文件.

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

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

所以,我查看了如何手动创建一个简单的二进制文件并找到 this super user post

You can use the printf command for it.

$ 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

这给出了预期的输出:

实际上,在写完这个 post 之后,我回去尝试了它,但没有文件的 write -> cat,它也能正常工作:

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

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

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

更多信息

我还花了一些时间与 Firecamp 的开发人员合作,结果发现他们的 Array Buffer 和 Array Buffer View 消息类型确实发送了值与实际数字的 ascii 代码。他们已经纠正了这个问题(我在他们通过我的金丝雀版本中确认了它)并且应该在 v2.0 中。