我正在使用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符号。
为什么输入流会混合消息?
提前致谢!
答案 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)
我认为您的问题出在您的方法中:
客户端一次发送多条消息时出现问题
套接字通常只是获取字节块,诀窍在于如何发送它们,如何标记消息的开始/结束以及如何检查它是否有错误(快速哈希可以做很多好事)所以在我看来,这种行为很好,如果你真的需要一次发送多条消息,你只需要处理你的消息。
套接字将控制你的信息是否是物理上完整的信息,但是你的问题是信息的内容。