Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字通信问题_Java_Sockets_Inputstream - Fatal编程技术网

Java套接字通信问题

Java套接字通信问题,java,sockets,inputstream,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(

我正在使用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)
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
当客户端一次发送多条消息时,服务器会混合消息,例如

MSG1: <MyMessage><Hello/>nul
MSG2: </MyMessage><MyMessage><Hello again /></MyMessage>nul
MSG1:nul
MSG2:nul
因此,消息1的尾部是消息2的一部分。 null表示java nul符号

为什么inputstream会混合消息


提前谢谢

套接字和InputStream只是一个字节流,而不是消息流。 如果要基于字符(如
\0
)分解流,则需要自己完成此操作

但是,在您的情况下,您的发送端似乎有一个bug,因为
\0
的位置不正确,在客户端很不可能是bug


顺便说一句:使用String+=效率非常低。

您从
InputStream
读取的数据将从操作系统中获取,并且无法保证如何分割。如果你想在新线上分裂,你可能想考虑这样的事情:

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)
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

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

我认为您的问题在于您的方法:

当客户端同时发送多条消息时,会出现问题

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


套接字将控制您的消息在物理上是否完整,但消息中的内容是您关心的。

您进行了错误的比较。检查字符串中是否有\0,然后认为它是一条消息。错。事实上,在第二个示例中,\0出现了两次

你应该换一种方式做。逐字符读取流(使用包装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()功能。

向我们展示通信双方的代码。我过去一次读取一个字节,但结果是速度变慢,导致延迟。因此,我将代码更改为读取字节块。我也尝试了换行方法,但我遇到了问题,因为我在客户端网站上使用Flash,在终止换行时出现了问题。@doorman,BufferedInputStream为您进行缓冲,以提高效率。@Daniel,您确定
c
可以
-1
作为其未签名项。。)经过一些实验后,我又遇到了延迟问题。缓冲似乎工作不正常。在我的项目中,连接了多个客户端,它们都在每秒发送消息。在阅读我在问题中编写的代码示例中的字节块时,这不是一个问题。我需要配置缓冲区以便在逐字符读取流时处理更多流量吗?@doorman:不,无论客户端数量多少,它都应该工作。也许虫子在别的地方?使用Wireshark分析发送的数据并验证其正确性。我尝试了readline方法,但我在客户端网站上使用Flash,正确终止线路时出现问题。您是否能够在消息之间发送任何内容以对其进行分隔?现在看来,您完全依赖XML来实现这一点。这将使在Java端拆分它们变得有点棘手。我在客户端使用0终止消息我建议用一个开始字符包装每条消息,然后是消息内容的快速哈希,然后是消息,然后是结束字符。然后,您可以通过散列识别每条消息的开始/停止(将其视为消息的标记),如果散列与您得到的内容不符,则您可以要求客户端重新发送,前提是您可以与客户端通信。字符串是不可变的,因此在调用它的每个循环中,它都会复制原始字符串,追加新字符串并创建组合字符串。请参阅@Daniel的解决方案以了解替代方案。