【问题标题】:Scanner.nextLine() blocks when using InputStream from Socket从 Socket 使用 InputStream 时的 Scanner.nextLine() 块
【发布时间】:2014-09-10 19:15:50
【问题描述】:

当我直接使用Socket.getInputStream() 接收数据时(没有像 Scanner 这样的接口),它不会阻塞。但是,当我尝试使用扫描仪时(类似于我们从System.in 接收字符串的方式),它确实如此。我想知道这是什么原因,以及连接的 Socket 提供给您的 InputStream 与 System 中的 InputStream in 有何不同。

用于测试的客户端(用于两个服务器)

挂起的代码:

public class Server {

    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(15180);
            Socket socket = ss.accept();

            Scanner scanner = new Scanner(socket.getInputStream());
            //read data from client
            while(true) {
                String data = scanner.nextLine();
                System.out.println("Received data!");
            }

        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

不阻塞的代码:

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(15180);
            Socket socket = ss.accept();

            //read data from client
            while(true) {
                int data = socket.getInputStream().read();
                System.out.println("Received data!");
            }

        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 听起来远程端没有发送面向线路的数据。
  • @ElliottFrisch 哇,谢谢。我认为在收到来自控制台的输入后我不必添加\n

标签: java sockets inputstream java.util.scanner


【解决方案1】:

(我想你已经想通了,但是……)

readLine() 方法返回当前行的其余部分。也就是说,直到下一个“行尾”序列或“流尾”的所有未使用的字符,以先出现的为准。它将阻塞,等待当前行(根据上述)可用。

因此,如果您的套接字 readLine() 调用阻塞,它正在等待远程发送行尾标记(例如 '\n'),或关闭其套接字输出流(这将导致“结束-of-stream”在此结束)。

问:为什么当您从控制台读取时它“工作”?

答:只要您按 ENTER,控制台就会向流中添加一个“行尾”序列。 (具体添加的序列取决于操作系统,但Scanner 类将处理所有常见的变体,以及一些不寻常的变体。)


这里的教训是,如果输入流是面向行的,你应该只使用Scanner.readLine();即,如果任何写入/生成的流都包含“行尾”标记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-15
    • 2021-09-30
    • 2015-03-03
    • 2019-11-29
    • 2015-05-23
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多