[英]Scanner.nextLine() blocks when using InputStream from Socket
當我直接使用Socket.getInputStream()
接收數據時(沒有像Scanner這樣的某種接口),它不會阻塞。 但是,當我嘗試使用掃描儀時(類似於我們從System.in
接收字符串的方式),它確實如此。 我想知道這個的原因,以及連接的Socket提供給你的InputStream in
與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();
}
}
}
(我想你已經想到了這個但是...)
readLine()
方法返回當前行的其余部分。 也就是說,所有未消耗的字符直到下一個“行尾”序列,或者“流的結束”,它始終是第一個。 它將阻塞,等待當前行(根據上述)可用。
因此,如果您的套接字readLine()
調用塊,它正在等待遠程發送行尾標記(例如'\\n'
),或關閉其套接字輸出流(這將導致“結束” - “在這一端”。
問:當你從控制台讀取時,為什么它“起作用”?
答:無論何時按Enter鍵,控制台都會向流添加“行尾”序列。 (確切地說,添加的序列是依賴於操作系統的,但Scanner
類將處理所有常見的變種,以及一些不尋常的變種。)
這里的教訓是,如果輸入流是面向行的,你應該只使用Scanner.readLine()
; 即如果寫入/生成的流包括“行尾”標記。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.