6

我正在编写基于 WebSocket 协议的服务器和客户端。

服务器是使用 Python 和 Twisted 制作的。

现在我可以将二进制数据从服务器发送到客户端并返回,唯一的问题是,根据一些消息来源,从浏览器发送的二进制数据的字节序是基于机器字节序的。我想确认一下,是真的吗?

如果这是真的,那么我是否应该以某种方式检查客户端有什么字节序并使用他的字节序从/向他读取/发送数据?检查客户端字节序的最佳方法是什么,只需从客户端发送

var view_buffer = new UInt8Array(new ArrayBuffer(1));
view_buffer[0] = 1;

这个数据,并在服务器上检查它是否返回 1 或 128?

4

5 回答 5

9

根据RFC 6455

多字节长度量以网络字节顺序表示。

网络字节顺序是大端。服务器和客户端都应该使用这个字节顺序,不管它们的本机顺序是什么。

在 Python 中,该struct模块可用于确保带有说明符的正确字节顺序'>'。我不确定它会如何在 Javascript 中完成。

于 2013-01-31T21:31:04.657 回答
1

Endianess 仅与由多于一个字节组成的数据类型相关。由于您正在使用一组 uint8 字节序,因此并不重要。

于 2013-01-31T21:28:27.347 回答
1

要检查字节顺序,您需要发送至少两个字节的值。

您不能仅通过发送单个字节进行检查,因为此时已为您整理好位级字节序。

因此,字节序仅对字节交换(如果需要)以及如果您尝试使用特定于字节序的规则打包单个位(例如在 C 中使用位域时)很重要。

如果您的问题与您自己在 WebSocket 有效负载中携带的消息有关,通常的过程是自己选择一个字节顺序,然后执行您必须执行的任何打包或解包操作,以将本机字节顺序转换为您的首选字节顺序。我知道的大多数协议都使用大端序,也就是“网络顺序”。

因此,如果您有一个 16 位值,请使用移位和按位运算符自行将其转换为两个 8 位字节,然后先发送最高字节,然后发送第二个字节。在服务器端,反转该过程。大多数服务器端语言都可以很容易地将值从网络顺序转换为本地字节顺序。

于 2013-01-31T21:31:59.487 回答
1

RFC 6455中有关于关闭消息顺序的注释:

如果有正文,正文的前两个字节必须是一个 2 字节无符号整数(按网络字节顺序),表示具有值 /code/ 在第 7.4 节中定义的状态代码。

因此,如果您要在 WS 消息中使用二进制数据,该协议通常会希望您使用大端序。我想这不是强制性的,通过。

如果您想允许其中任何一个,您可以在消息的开头添加一个幻数。那将是 2 个不同的字节,例如 (('M' << 8) | 'G')。如果你收到“M”然后是“G”,它是大端。如果你收到“G”然后是“M”,它是小端。现在每条消息都会告诉你它的字节序。没有更多的猜测工作。

正如 Mark Ransom 在评论中指出的那样,可以从 JavaScript 以任一字节序发送数据,但必须交换所有字节可能很烦人。因此,具有指示当前字节顺序的 2 字节值通常是解决问题的一个非常好的方法。接收数据的服务器可以检查这两个字节并相应地交换 short、int、long int 数据。

于 2018-04-13T16:03:44.607 回答
0

让客户端向服务器发送 126 字节或更多(但小于 65535)(例如 200)的文本消息。Payload_Length 字段将为 126。

然后检查扩展有效负载长度的下两个字节,以确定客户端是否以大端(可能)发送它,或者客户端是否搞砸并以小端格式发送。

对于大端,紧挨着 8 位有效负载长度的字节(应该是 126 表示接下来的两个字节实际上包含实际有效负载长度)应该是 16 位长度的最高有效字节。

于 2019-06-08T20:34:04.010 回答