套接字multithreading – 读取输入流暂停线程

我正在测试本地机器上的套接字。 我正在尝试使用线程在一个程序中运行套接字和服务器。 我的服务器是一个echo服务器,因此它会发回它收到的任何消息。 我的问题是,当我在客户端和服务器上启动两个线程时,当它们到达我从输入流中读取的部分时,它们会“冻结”。 它适用于客户端发送消息的部分。 之后,它只是停止,因为看起来客户端正在等待消息,即使我已经通过写入输出流向服务器发送了消息,服务器也是如此。 代码有什么问题?

Client.java

@Override public void run() { try { Socket socket = new Socket("localhost", 22600); BufferedReader br = new BufferedReader(new InputStreamReader( socket.getInputStream())); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())); BufferedReader input = new BufferedReader(new InputStreamReader( System.in)); System.out.println("Client 1"); while (true) { System.out.print("\nEnter text : "); String inputText = input.readLine(); writer.write(inputText); System.out.println("Client 2"); System.out.println("Client 3"); String s = br.readLine(); System.out.println("CLIENT RECEIVED : " + s); } } catch (Exception e) { e.printStackTrace(); } } 

Server.java

 @Override public void run() { try { ServerSocket server = new ServerSocket(22600); Socket socket = server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader( socket.getInputStream())); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())); System.out.println("Server 1"); while (true) { System.out.println("Server 2"); String s = br.readLine(); System.out.println("Server 3"); if (s == null) { System.out.println("NULL SERVER SIDE ERROR"); break; } writer.write("ECHO : " + s); System.out.println("SYSOUT ECHO " + s); } server.close(); } catch (Exception e) { e.printStackTrace(); } } 

您正在编写一个字符串,其末尾没有行尾。

  String inputText = input.readLine(); writer.write(inputText); System.out.println("Client 2"); 

inputText字符串不包括您键入的行尾。 然后你按原样把它写到服务器上。 但是,服务器尝试读取一行:

  String s = br.readLine(); System.out.println("Server 3"); 

所以它会一直等到客户端发送换行符。 但到目前为止,客户端正在等待服务器的回答,现在它们已陷入僵局。

因此,您应该将writer.newLine()添加到客户端,以及服务器的echo,它会遇到同样的问题。 在每次写入之后,还建议在服务器和客户端上使用writer.flush() 。 否则,它可能会在实际写入之前等待缓冲区已满,并且会导致相同的死锁。

BufferedReader的readLine方法需要一个新的行终止符来返回一个值(除非到达Stream的末尾),然后返回没有该字符的行。 所以客户

  1. 从用户读取一行到变量inputText
  2. 客户端将inputText写入OutputStream
  3. 服务器接收数据,但等待它收到一个新行(它没有)。

如果您希望使用新行作为通信分隔符,请将其附加到发送数据的末尾

 writer.write(inputText + "\n");