[客户端通过IntelliJ断开连接时ServerSocket无限读取

问题描述 投票:0回答:1

我有一个简单的TCP服务器:

public class ServerSocketRunner {

  public static void main(String[] args) throws Exception {
    ServerSocket serverSocket = new ServerSocket(9000);

    while (true) {
      Socket socket = serverSocket.accept();

      new Thread(() -> {
        System.out.println("New client connected");
        try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));) {

          String inputLine, outputLine;
          do {
            inputLine = in.readLine();
            System.out.print("Received: " + inputLine);
            String serverResponse = "Message Received: " + now();
            System.out.println("Sending: " + serverResponse);
            out.println(serverResponse);
          } while (!"bye".equals(inputLine));

          socket.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }).start();
    }
  }
}

和客户

public class ClientRunner {

  public static void main(String[] args) throws Exception {
    try (Socket socket = new Socket("localhost", 9000);
        Scanner input = new Scanner(socket.getInputStream());
        PrintWriter output = new PrintWriter(socket.getOutputStream(), true)) {

      Scanner userEntry = new Scanner(System.in);
      String message, response;
      do {
        System.out.print("Enter message: ");
        message = userEntry.nextLine();
        output.println(message);
        response = input.nextLine();
        System.out.println("\nSERVER> " + response);
      } while (!message.equals("bye"));
    }
  }
}

客户端发送用户类型的消息,服务器以“收到消息”和时间戳作为响应。除一种情况外,其他所有方法都运行良好。如果我使用IntelliJ关闭客户端,请关闭,然后单击“断开连接”按钮

enter image description here

服务器无限期开始打印

Received: nullSending: Message Received: 2019-10-03T14:44:36.962
Received: nullSending: Message Received: 2019-10-03T14:44:36.962
Received: nullSending: Message Received: 2019-10-03T14:44:36.962
...

所以它不断收到换行符的空消息。断开连接行为已解释here

断开连接(如果可用)--->如果选择此选项,则正在运行的进程将断开连接。

因此,这意味着断开连接使进程继续运行,但是IntelliJ将不再附加到该进程。但这仍然不能解释为什么服务器不断收到新的(空)消息。

任何人都可以解释这种行为吗?

java sockets intellij-idea serversocket
1个回答
0
投票

客户端已断开连接,因此客户端与服务器之间的连接已断开。但是您的代码无法处理该问题。当连接断开时,它构成“流的末尾”,BufferedReaderreadLine函数返回null。这就是它在输出中告诉您的内容:

Received: null [...]

您需要检查null返回值并中断循环。

    inputLine = in.readLine();
    if (inputLine == null) {
        System.out.print("Client disconnected. Leaving\n");
        break;
    }

客户端和服务器均应执行该测试。在真实的网络中,您永远不知道对等方何时消失。

请参见https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#readLine--处的文档(返回: ... 如果已到达流的末尾,则为null]]

((我不完全知道IntelliJ在这里发生了什么,但是显然服务器线程仍在运行。服务器和客户端大概在单独的子进程或线程中运行。)

© www.soinside.com 2019 - 2024. All rights reserved.