如何解析通过 TCP 收到的损坏消息

发布于 2024-10-10 06:12:58 字数 1468 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白鸥掠海 2024-10-17 06:12:58

TCP中没有“消息”这样的东西。它是一个面向流的协议。当然,在较低级别,它是在单独的数据包中传输的,但是您无法控制它,并且您看到的内容可能与这些数据包不同。您只需在任何特定时刻读取接收缓冲区中可用的内容即可。您可能会认为您的消息已被分解,但您也可能会遇到多条消息组合成一个片段到达的情况。

因此,在阅读消息时,您应该使用某种分隔符来确定消息的结束位置,或者使用包含消息长度的标头。如果您发送简单的字符串,将它们编码为 UTF-8 并以空字节终止它们应该可以正常工作。显然,对于更复杂的事情,您需要更复杂的方法。

There is no such thing in TCP as "message". It is a stream-oriented protocol. Of course, at lower levels it is transmitted in separate packets, but you have no way to control it and what you are seeing can be different from those packets. You just read as much as available in the receiving buffer at any particular moment. You may perceive your messages as broken down, but you may as well encounter a situation where several messages arrive as combined into one piece.

So when reading a message you should either use some sort of delimiter to figure out where your message ends, or use a header with message length. If you are sending simple strings, encoding them as UTF-8 and terminating them with null bytes should work fine. For more complicated things you'll need more complicated approach, obviously.

梦回旧景 2024-10-17 06:12:58

不过关于在消息中添加标题前缀吗?发送带有传输长度和校验和的标头是很常见的。这样您就可以分配适当大小的缓冲区并验证数据完整性。

Though about prefixing your messages with a header? It's very common to send a header with the length and checksum of the transmission. This way you're able to allocate appropriate sized buffers and verify data integrity.

凉月流沐 2024-10-17 06:12:58

首先发送长度的简单示例。注意:我在读取时检查长度,因为无效的消息长度可能会导致 OutOfMemoryException,这可能会令人困惑/令人震惊。

public static void writeBytes(DataOutput out, byte [] bytes) throws IOException {
    out.writeInt(bytes.length);
    out.write(bytes);
}

public static byte[] readBytes(DataInput in) throws IOException {
    int len = in.readInt();
    if (len < 0 || len > 1 << 24) throw new StreamCorruptedException("Invalid message length "+len);
    byte [] bytes = new byte[len];
    in.readFully(bytes);
    return bytes;
}

A simple example of sending the length first. Note: I check the length when reading as an invalid message length can result in an OutOfMemoryException which can be confusing/alarming.

public static void writeBytes(DataOutput out, byte [] bytes) throws IOException {
    out.writeInt(bytes.length);
    out.write(bytes);
}

public static byte[] readBytes(DataInput in) throws IOException {
    int len = in.readInt();
    if (len < 0 || len > 1 << 24) throw new StreamCorruptedException("Invalid message length "+len);
    byte [] bytes = new byte[len];
    in.readFully(bytes);
    return bytes;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文