簡體   English   中英

從Socket使用InputStream時,Scanner.nextLine()會阻塞

[英]Scanner.nextLine() blocks when using InputStream from Socket

當我直接使用Socket.getInputStream()接收數據時(沒有像Scanner這樣的某種接口),它不會阻塞。 但是,當我嘗試使用掃描儀時(類似於我們從System.in接收字符串的方式),它確實如此。 我想知道這個的原因,以及連接的Socket提供給你的InputStream inSystemInputStream 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();
        }
    }
}

(我想你已經想到了這個但是...)

readLine()方法返回當前行的其余部分。 也就是說,所有未消耗的字符直到下一個“行尾”序列,或者“流的結束”,它始終是第一個。 它將阻塞,等待當前行(根據上述)可用。

因此,如果您的套接字readLine()調用塊,它正在等待遠程發送行尾標記(例如'\\n' ),或關閉其套接字輸出流(這將導致“結束” - “在這一端”。

問:當你從控制台讀取時,為什么它“起作用”?

答:無論何時按Enter鍵,控制台都會向流添加“行尾”序列。 (確切地說,添加的序列是依賴於操作系統的,但Scanner類將處理所有常見的變種,以及一些不尋常的變種。)


這里的教訓是,如果輸入流是面向行的,你應該只使用Scanner.readLine() ; 即如果寫入/生成的流包括“行尾”標記。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM