从套接字使用InputStream时Scanner.nextLine()会阻塞 [英] Scanner.nextLine() blocks when using InputStream from Socket

查看:140
本文介绍了从套接字使用InputStream时Scanner.nextLine()会阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I receive data using Socket.getInputStream() directly (without some kind of interface like Scanner), it doesn't block. But, when I try to use a Scanner (similar to how we receive Strings from System.in), it does. I was wondering the reason for this, and how the InputStream that a connected Socket supplies to you is different from the InputStream in in System.

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

The Client used for testing (used for both servers)

挂起的代码:

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

推荐答案

(我想您已经知道了,但是...)

(I think you've already figured this out but ...)

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

The readLine() method returns the rest of the current line. That is, all unconsumed characters up to the next "end of line" sequence, or the "end of stream", which ever comes first. It will block, waiting until the current line (according to the above) is available.

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

So if your socket readLine() call blocks, it is waiting for the remote to either send an end-of-line marker (e.g. '\n'), or close its socket output stream (which will result in an "end-of-stream" at this end).

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

Q: Why does it "work" when you read from the console?

A:每当您按ENTER键时,控制台就会向流中添加一个行尾"序列. (确切地说,添加的序列取决于操作系统,但是Scanner类将处理所有常见的变体,以及一些不寻常的变体.)

A: The console adds an "end-of-line" sequence to the stream whenever you hit ENTER. (Precisely what sequence is added is OS dependent, but the Scanner class will cope with all common varieties, and some unusual ones too.)

这里的教训是,如果输入流是面向行的,则仅应使用Scanner.readLine();否则,请使用Scanner.readLine().也就是说,无论编写/生成的内容流中是否包含行尾"标记.

The lesson here is that you should only use Scanner.readLine() if the input stream is line oriented; i.e. if whatever wrote / generated the stream is including "end-of-line" markers.

这篇关于从套接字使用InputStream时Scanner.nextLine()会阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆