当前位置: 首页 > 面试题库 >

从套接字使用InputStream时Scanner.nextLine()会阻塞

杜河
2023-03-14
问题内容

当我Socket.getInputStream()直接使用(没有诸如Scanner之类的界面)接收数据时,它不会阻塞。但是,当我尝试使用Scanner时(类似于我们从接收字符串的方式System.in),它确实可以。我想知道这样做的原因,以及所连接的Socket提供给您的InputStream与InputStream inin的不同之处System

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

挂起的代码:

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();
        }
    }
}

问题答案:

(我认为您已经知道了这一点,但是…)

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

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

问:当您从控制台读取内容时,为什么它“起作用”?

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

这里的教训是,仅Scanner.readLine()当输入流是面向行的时才应使用;也就是说,无论写/生成的内容是什么,流中都包含“行尾”标记。



 类似资料:
  • 我有一个小问题与Android和IOS之间实现套接字连接。当我使用我的应用程序连接两个Android运行设备时,一切正常。但是当我必须从Iphone应用程序接收一些数据时,我的readStream函数被阻塞,我可以在另一个部分关闭套接字后接收所有数据,这样我就不能返回任何响应。以下是我用来听的: 这里是我用来将转换为的函数: Iphone/Android应用程序的工作原理如下: 首先,它创建Soc

  • 问题内容: 为什么有人会喜欢阻止写而不是非阻止写?我的理解是,仅当您想确保写方法返回后,另一端获得了TCP数据包时,才希望阻止写操作,但是我什至不知道这是可能的。您将必须刷新,而刷新则必须刷新 底层操作系统的写套接字缓冲区 。那么,无阻塞套接字写是否有任何缺点?就性能而言,拥有较大的底层写套接字是否会缓冲一个不好的主意?我的理解是,底层套接字写缓冲区越小,当底层套接字缓冲区已满且isWritabl

  • 问题内容: 在Linux中,如果我们从一个线程调用阻塞并从另一个线程关闭同一个套接字,则不会退出。 为什么? 问题答案: 检查是否已关闭套接字的所有文件描述符。如果在“远程”端有任何打开的端口(假设这是您尝试关闭的端口),则“ 对等方尚未执行有序的关闭 ”。 如果仍然不起作用,请在远端调用,无论引用计数如何,都将关闭套接字。

  • 问题内容: 我想创建一个非阻塞连接。像这样: 为此,我使用了另一个线程,无限循环和Linux epoll。像这样(伪代码): 如果我先运行服务器,然后运行客户端,那么一切正常。如果我先运行客户端,请稍等一会儿,再运行服务器,然后客户端将无法连接。 我究竟做错了什么?也许可以做不同的事情? 问题答案: 您应该使用以下步骤进行异步连接: 用创建套接字 开始与 如果返回值既不是也不是,则中止并返回错误

  • 问题内容: 这是代码,但出现错误: 可以从插座接收使用吗? 问题答案: 不。当您有字节数组时,要使用该数组,并且要像文件一样从数组中读取,就可以使用。如果只想从套接字读取字节数组,请执行以下操作: 该变量将包含实际读取的字节数,并且数据当然将在array中。

  • 问题内容: 尝试使用中的方法时遇到麻烦。 这是我尝试过的: 示例1:此示例按预期方式工作。该行;等待输入,然后再继续。 产生输出: 示例2:此示例无法正常工作。本示例使用while循环以及结构允许用户选择要执行的操作。一旦程序到达;,它就不会等待输入,而是执行该行;。 产生输出: 这使得不可能输入句子。 为什么示例不能按预期工作?唯一之间的区别。和是那个 具有循环和结构。我不明白为什么这会影响的行