开发者

Java socket communication problem

开发者 https://www.devze.com 2023-02-19 05:18 出处:网络
I am using Java for socket communication. The server is reading bytes from the client like this: InputStream inputStream;

I am using Java for socket communication. The server is reading bytes from the client like this:

InputStream inputStream;
final int BUFFER_SIZE = 65536;
byte[] buffer = new byte[BUFFER_SIZE];
String msg="";

while (msg.indexOf(0)==-1 && (read = inputStream.read(buffer)) != -1)
{
    msg += new String(buffer, 0, read);
}
handleMessage(msg)

There is a problem when a client is sending multiple messages at once the server mixes the messages e.g.

MSG1: <MyMessage><Hello/>nul
MSG2: </MyMessage><MyMessage><Hello again /></MyMessage>nul

So the tail of Message 1 is part of Message 2. The null represents the java nul symbol.

Why does the inputstream mix the m开发者_如何学Goessages?

Thanks in advance!


You are doing the wrong comparison. You check if there is a \0 anywhere in the String, and then believe it is a single message. Wrong. In fact, in the second example, the \0 comes twice.

You should do it differently. Read from the Stream in char by char (Using a wrapping BufferedInputStream, else the performance will be awful), and skip when the \0 is reached. Now the message is complete, and you can handle it.

InputStream bin = new BufferedInputStream(inputStream);
InputStreamReader reader = new InputStreamReader(bin);
StringBuilder msgBuilder = new StringBuilder();
char c;
while ( (c=reader.read()) != -1 ) 
{
    msgBuilder .append(c);
}
handleMessage(msgBuilder.toString())

Even better would be using the newline character for line separation. In this case you could just use the readline() functionality of BufferedReader.


Sockets and InputStream are only a stream of bytes, not messages. If you want to break up the stream based on a char like \0 you need to do this yourself.

However, in your case it appears you have a bug on your sending side as the \0 isn't the right places and it is highly unlikley to be a bug on the client side.

btw: Using String += is very inefficient.


The data you read from InputStream will come in as it's available from the OS and there's no guarantee on how it will be split up. If you're looking to split on new lines you might want to consider something like this:

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

And then use reader.readLine() to get each line as a String that's your message.


I think your problem is in your approach:

There is a problem when a client is sending multiple messages at once

Sockets in general just get chunks of bytes and the trick is in how you send them, how do you mark start/end of a message and how do you check it for errors (quick hash can do a lot of good) so the behaviour is fine in my eyes, you just need to work on your messaging if you really need to send multiple messages at once.

Sockets will control if your message is integral physical wise but what is IN the message is your concern.

0

精彩评论

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