Websockets 有时会发送不完整的数据

Posted

技术标签:

【中文标题】Websockets 有时会发送不完整的数据【英文标题】:Websockets sometimes send incomplete data 【发布时间】:2016-02-06 15:43:30 【问题描述】:

我有一个用 C++ 构建的 websocket 服务器,目前用作基本的聊天服务器。

如果我要发送一个基本的“嗨”消息,数据会是这样的:

Binary: 10000001 10000010 10110110 00100110 01100101 01100011 11011110 01001111
Byte size: 8
Decoded: hi

但有时它不会发送完整的消息。这种情况的一个例子如下:

Binary: 10000001 10000010 01110111 00100010 11011011
Byte size: 5

它正在发送正确的数据,但它几乎就像被完全切成两半一样。

我的接收代码如下所示:

while (true)

    char buffer[BUFFER_LENGTH] = ""; // (1024)

    recv(*mSocket, buffer, BUFFER_LENGTH, 0);

    // Data decoding code
    // ...

我对 TCP 的理解是协议本身会确保所有数据包都到达目的地。有人可以解释为什么我会丢失数据吗?

【问题讨论】:

您确定错误出在接收方而不是发送方吗?此外,TCP 套接字是流式传输,没有固定的数据包边界,这意味着单个 recv 调用可以接收不到完整的消息,并且您需要循环调用 recv 直到您收到一个完整的消息。这就是为什么构建在 TCP 之上的协议通常具有明确指定的标头,该标头通常包含有效负载的长度。 TCP 是基于流的,因此您无法确定每次recv 都会收到您的协议消息之一。可能有两条消息或半条消息——在这种情况下,如果您再次recv,您将获得下半部分。也可能是您的 C++ 服务器在发送每条消息后没有刷新。 啊,对。我明白了,谢谢。一定是这样,我只调用一次。 【参考方案1】:

首先,确保客户端正在刷新。

其次(如果我理解您的问题),虽然 WebSocket 是使用 Socket 实现的,但请注意 WebSocket 不是 Socket。您不能仅在服务器中使用 TCP 套接字调用从 WebSocket 客户端检索数据。每个 WebSocket send() 都会发送 WebSocket 帧数据。服务器已检查传入的字节流,并在 WebSocket 帧中的适当区域中查找“消息数据”。此外,WebSocket 数据可能不必在一个 WebSocket 帧中发送;您还需要检查框架以查看是否需要检查另一个 WebSocket 框架以完成“消息数据”。有关 WebSocket 协议,请参阅 IETF 规范:https://www.rfc-editor.org/rfc/rfc6455

【讨论】:

以上是关于Websockets 有时会发送不完整的数据的主要内容,如果未能解决你的问题,请参考以下文章

Websockets 消息完整性

如何确保消息使用 WebSockets 到达目的地?

是否可以在不使用 Web 浏览器的情况下通过 websockets 交谈?

如何从网站向不支持 Websockets 的 MQTT 代理发送消息?

用于 websockets 内部的 Chrome DevTools 网络工具

Websockets 不能发送大数据