读取()时BufferedReader阻塞

我试图创建一个简单的聊天程序,与“服务器”和客户端,现在我的问题是程序阻止从服务器读取消息到客户端,反之亦然。 此示例解决了从客户端到服务器的消息问题。

我在服务器端的示例:

private Reader input; private Writer output; try { server = new ServerSocket(this.port); while (true) { Socket connection = server.accept(); serverDisplay("We have a connection"); input = new BufferedReader(new InputStreamReader( connection.getInputStream())); output = new BufferedWriter(new OutputStreamWriter( connection.getOutputStream())); int c; StringBuffer sb = new StringBuffer(); // This is where it blocks, the input stream should return -1 at the end of the // stream and break the loop, but it doesnt while ((c = input.read()) != -1) { sb.append((char) c); } serverDisplay(sb.toString()); } } catch (IOException e) { System.out.println("IO ex in the server"); } 

为了在客户端发送消息,我有以下代码:

 output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream())); 

 private void sendMessage(String message) { displayMessage(message); try { output.write(message); output.flush(); } catch (IOException e) { System.out.println("IO ex at sendMessage client"); } } 

它读取我发送的所有字符(从客户端到服务器;用Sys确认),但是当它应该读取流的末尾(-1)时,它会挂起

我试图在while循环中打印“c”以查看它返回的值,它只是不进入循环,也不会破坏它,它只是挂在那里。

我知道有一些问题已经与这个问题有关,但我没有找到解决我的问题的方法。

如果我使用的话,奇怪的是(至少对我而言):

 output = new ObjectOutputStream(connection.getOutputStream()); input = new ObjectInputStream(connection.getInputStream()); 

和:

 while ((message = (String) input.readObject()) != null) 

代替:

 input = new BufferedReader(new InputStreamReader(connection.getInputStream())); output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream())); 

和:

 while ((c = input.read()) != -1) 

洞的事情有效。 然而,这不是我想要的方式,通过读取BufferedReader / Writer的API,输入/输出流逻辑,我认为我的代码应该工作。

先谢谢你。

在发送流(或整个套接字)关闭之前,不会到达接收方的流末端。

发送端的output.close()将使接收端看到流的结束。

如果需要将流用于多个消息,则需要在应用程序协议中引入帧结构,以便接收方可以确定消息边界。 这可以简单到为每条消息添加消息长度(以字节为单位)。

因为您使用String作为整个消息。 您可以使用DataInputStreamDataOutputStream流装饰器使用readUTF()writeUTF(String)为您构建消息。 writeUTF(String)基本上通过在写入字符串之前将其长度写入流来构造字符串。 readUTF()然后读取此长度,然后知道在返回之前需要从流中读取多少数据。

例:

输出:

 DataOutputStream output = new DataOutputStream(connection.getOutputStream()); private void sendMessage(String message) { displayMessage(message); try { output.writeUTF(message); output.flush(); } catch (IOException e) { System.out.println("IO ex at sendMessage client"); } } 

输入:

 DataInputStream input = new DataInputStream(connection.getInputStream()); String message = input.readUTF(); serverDispaly(message);