开发者

How to parse broken messages received through TCP [closed]

开发者 https://www.devze.com 2023-02-01 23:25 出处:网络
Closed. This question needs debugging details. It is not currently accepting answers. 开发者_运维知识库
Closed. This question needs debugging details. It is not currently accepting answers.
开发者_运维知识库

Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.

Closed 2 years ago.

Improve this question

I'm sending a string message from my client application to my server application using sockets. I'm using DataOutputStream to send from client and DataInputStream to receive the message in my server. I'm sending one string from the client but I noticed that when it gets to the server, it is sometimes broken into several messages. How do I handle this or what's the best way to handle this?

I can probably read each broken message received and check each character for a delimeter to know that it is the end of one message. But is there a better way to handle this?


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.


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.


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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消