Java套接字通信问题

时间:2011-03-24 10:17:04

标签: java sockets inputstream

我正在使用Java进行套接字通信。服务器正在从客户端读取字节,如下所示:

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)

当客户端一次发送多条消息时服务器混合消息,例如

,就会出现问题
MSG1: <MyMessage><Hello/>nul
MSG2: </MyMessage><MyMessage><Hello again /></MyMessage>nul

因此消息1的尾部是消息2的一部分。 null表示java nul符号。

为什么输入流会混合消息?

提前致谢!

4 个答案:

答案 0 :(得分:1)

你做错了比较。您检查字符串中是否有\ 0,然后相信它是单个消息。错误。事实上,在第二个例子中,\ 0来了两次。

你应该采用不同的方式。通过char读取来自char的char(使用包装BufferedInputStream,否则性能会很差),并在到达\ 0时跳过。现在消息已经完成,您可以处理它。

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())

更好的方法是使用换行符进行行分离。在这种情况下,您可以使用BufferedReader的readline()功能。

答案 1 :(得分:0)

套接字和InputStream只是一个字节流,而不是消息。 如果你想基于像\0这样的字符来分解流,你需要自己做。

但是,在你的情况下,你的发送方似乎有一个错误,因为\0不是正确的地方,而且客户端的错误是非常不可能的。

btw:使用String + =是非常低效的。

答案 2 :(得分:0)

您从InputStream读取的数据将从操作系统中获取,并且无法保证它将如何拆分。如果您希望拆分新行,可能需要考虑这样的事情:

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

然后使用reader.readLine()将每一行作为String获取,这是您的信息。

答案 3 :(得分:0)

我认为您的问题出在您的方法中:

  

客户端一次发送多条消息时出现问题

套接字通常只是获取字节块,诀窍在于如何发送它们,如何标记消息的开始/结束以及如何检查它是否有错误(快速哈希可以做很多好事)所以在我看来,这种行为很好,如果你真的需要一次发送多条消息,你只需要处理你的消息。

套接字将控制你的信息是否是物理上完整的信息,但是你的问题是信息的内容。