【问题标题】:Sending data as binary via websockets encodes numbers as text通过 websockets 以二进制形式发送数据将数字编码为文本
【发布时间】:2021-01-07 23:14:51
【问题描述】:

我正在开展一个项目,我将通过 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 发送二进制数的正确方法是什么?我是否只是误解了二进制功能应该如何工作,就像期望我将我的数字作为字符串发送并将它们转换回另一端的数字一样?

【问题讨论】:

  • 可以以二进制格式发送数字。如果没有看到您编写 WebSocket 消息的实际代码,我无法回答任何问题(请不要发布代码截图,它们无法阅读)......您可能正在将数字转换为服务器上的字符串,或者您可能会在客户端以字符串格式发送数字 - 如果不观察代码,我怎么知道?
  • P.S.,我不知道您的 WebSocket 客户端(我使用浏览器的控制台),但在我看来,您可能正在发送从键盘输入的字符串(而不是作为二进制字符串发送而不是 UTF-8 字符串)。尝试使用实际的二进制数据管道传输文件。
  • @Myst 在我编写 websocket 客户端代码的地方没有代码。我直接从上面的客户端测试人员那里发送消息。我使用 firecamp(上面的 GUI)和 websocat(上面的 cli 工具)。我在研究时想出了答案。我现在正在输入答案。
  • 啊,阅读您的第二条评论,我们得出了相同的解决方案(即管道二进制文件与在控制台中输入二进制文件)

标签: javascript websocket iot


【解决方案1】:

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

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

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

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

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

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

所以,我查了一下如何手动创建一个简单的二进制文件,发现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

这给出了预期的输出:

实际上,在写完这篇文章后,我回去尝试了没有文件的 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 中。

【讨论】:

    猜你喜欢
    • 2012-11-16
    • 2012-12-05
    • 2014-11-30
    • 2011-04-21
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2013-09-18
    • 2012-02-18
    相关资源
    最近更新 更多