2011-10-21 86 views
2

我在學習使用Java的套接字,並且成功將數據發送到在我自己的機器中運行的ServerSocket。當我嘗試使用readline從這個套接字讀取(所以我只能迴應我自己發送的消息)我的程序掛起,不會返回。BufferedReader readLine方法掛起並阻止程序

下面的代碼:

public static void main(String[] args) throws UnknownHostException, IOException { 

    TCPClient cli = new TCPClient("127.0.0.1", "15000"); 
    try { 
     cli.ostream.writeUTF("Teste"); 
     String echo = cli.istream.readLine(); //it hangs in this line 
     System.out.println(echo); 
    } 

的TcpClient是我定義的,所以我可以測試我的節目一個簡單的界面上使用我homwework前擺一類。這裏是代碼:

public class TCPClient { 

public DataOutputStream ostream = null; 
public BufferedReader istream = null; 

public TCPClient(String host, String port) throws UnknownHostException { 
    InetAddress ip = InetAddress.getByName(host); 

    try { 
     Socket socket = new Socket(host, Integer.parseInt(port)); 

     ostream = new DataOutputStream(socket.getOutputStream()); 
     istream = new BufferedReader(new InputStreamReader(socket.getInputStream())); 


    } catch (IOException ex) { 
     Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

我的服務器非常簡單。連接建立後,它進入這個循環並保持在這裏,直到我關閉客戶端(由於無限循環)。之後,一些異常處理將其返回到連接開始之前的位置。

  while(true){ 
       String msg = istream.readLine(); 
       System.out.println("Arrived on server: " + msg); //just works on debug 
       ostream.writeUTF("ACK: " + msg); 
       ostream.flush(); 
      } 

我看不到我在想什麼。

PS:奇怪的是,如果我調試服務器,我可以看到消息到達那裏(例如我可以打印它),但如果我只是運行此代碼,這是不可能的。這是否有一些我忽略的併發關係?

THX

+1

服務器是做什麼的?如果它沒有回覆你的消息,或者沒有刷新它的寫入,那麼當然客戶端將無限期地等待直到從服務器發送一行。 –

+0

我將用服務器的無限循環編輯帖子,同時回覆消息 –

回答

11

問題是readLine嘗試讀取一行。直到它確定已到達行尾爲止,它不會返回行。這意味着它期望換行符或通信結束。由於服務器不發送任何新行字符並且不關閉流,客戶端無限期地等待。

+1

就是這樣!在ostream.writeUTF(「ACK:」+ msg)中放置'\ n';工作。現在唯一的疑問是,我的客戶端上出現了2個不可打印的字符。他們能成爲什麼? –

+0

您可以在一側以UTF編寫,並在另一側使用平臺的默認編碼進行讀取。始終使用Writer來寫字符。始終使用指定特定的顯式編碼的OutputStreamWriter來封裝輸出流。執行相同的操作:始終使用Reader,並使用指定相同特定編碼的InputStreamReader來包裝輸入流。 –

+0

@Thiago Moraes它們是由Javadoc中記錄的writeUTF()放置的長度字前綴。另請參閱我的答案。 – EJP

1
cli.ostream.writeUTF("Teste"); 

不應該這是包含一個新的生產線?否則,讀取方法將等待我認爲的新行。

也如建議您可以嘗試寫入後沖洗ostream。

+0

ostream是輸出流。 OP表示服務器正確接收到此消息。問題是客戶端沒有收到來自服務器的答案。 –

+0

我刷新了ostream並且現在給我的字符串添加了一個'\ n',之前我沒有這樣做。但問題仍然存在相同=/ –

1

writeUTF()不寫一行。看到Javadoc。 writeUTF()用於readUTF()。讀者可以與作家一起使用。因此,將DataOutputStream更改爲BufferedWriter並調用write(),然後調用newline()。

+0

我相信我明白你的意思,但考慮到我不是英語母語的人,所以我需要Unicode支持。在我的情況下,將推薦什麼類的組合? –

+0

@ThiagoMoraes我有一個錯字。使用讀者和作家,並指定字符集。 – EJP

相關問題