1

我正在創建一個簡單的服務器/客戶端應用程序。服務器將socket.getInputStream()包裝在Scanner中。客戶端從System.in獲取用戶輸入,並將其發送到服務器並使用PrintWriter。服務器評估scanner.hasNext()爲true,但會在以下scanner.next()調用中阻塞。按照javadocs:java掃描程序塊在.next()時它不應該

即使先前調用hasNext()返回true,此方法也可能在等待輸入進行掃描時阻塞。

好吧..這是怎麼回事? 編輯:值得注意的是,當客戶端終止時,服務器現在繼續撥打scanner.next()。額外的問題:客戶instanciates PrintWriterautoFlush參數爲true,但我需要在每次致電.write()後刷新。爲什麼?下面是我的代碼的MCV:

import java.io.IOException; 
import java.net.ServerSocket; 
import java.util.Scanner; 

public class MCVServer { 
    public static void main(String[] args) throws IOException { 
     ServerSocket server = new ServerSocket(1337); 
     Scanner fromClient = new Scanner(server.accept().getInputStream()); 
     while (fromClient.hasNext()) { 
      System.out.println("server heard something: "); 
      System.out.println(fromClient.next()); 
     } 
    } 
} 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.util.Scanner; 

public class MCVClient { 

    public static void main(String[] args) throws UnknownHostException, IOException { 
     Socket socket = new Socket("localhost", 1337); 
     Scanner input = new Scanner(System.in); 
     PrintWriter output = new PrintWriter(socket.getOutputStream(), true); 

     while(true) { 
      output.write(input.next()); 
      output.flush(); 
     } 
    } 
} 

回答

1

方法next()和hasNext()的行爲按預期工作。方法hasNext只會在到達流末尾時返回false。如果next()方法還沒有到達流的末尾或者它正在等待輸入,則next()方法將被阻止。

獎金問題也是一個簡單的問題。按照爲PrintWriter類的文檔:

不像的PrintStream類,如果啓用自動刷新,它只會在完成時被調用的的println,printf或format方法之一,而不是當一個換行符恰巧被輸出。這些方法使用平臺自己的行分隔符而不是換行符。

因此,爲了使用autoflushing,你需要的println替換寫入方法:

while (true) { 
     output.println(input.next()); 
} 
+0

我不明白。由於流是'System.in',它永遠不會到達流的結尾,對吧?但爲什麼是'。next()'等待輸入?流中有東西。 – user2651804

+0

在客戶端,由於System.in被實現(這是一個BufferedInputStream)的方式,需要讀取一個'\ n'字符以將其緩衝區刷新到Scanner對象。 – dliber

0

使用NextLine(),而不是下一個()

+1

它不工作,爲什麼你認爲它會嗎? – user2651804

+0

NextLine將強制讀取整行而不僅僅是單詞。這可能會導致Block。另外,在服務器中用'code'代替(來自Client.hasNext()){}代碼的'code'代碼(true){}'代碼',以便繼續讀取。 –

1
  1. 一個scanner.hasNext()讀取,直到開始的下一個令牌可以被檢測到。這並不意味着整個令牌已被讀取或接收。但是scanner.next()必須讀取所有的標記;因此可能會阻止。

  2. Autoflush僅在調用方法println,printf或格式後生效。

+0

如果檢測到'下一個標記'的開始,它意味着一個標記已經結束,爲什麼do''t.next()'沒有收到?你的意思是說它並不意味着已經收到了NEXT令牌? – user2651804

+0

Oooh ..我明白了! – user2651804

相關問題