2013-06-05 42 views
0

這是我的Socket測試程序。 我的問題是,當我執行下面的代碼。第一次在Socket InputStream上調用read()之後,它按預期進行阻塞。 但是當循環再次返回read()時,它不會再次在read()上被阻塞?因此,它結束了一個緊密無盡的循環。第二次調用後Socket讀()不會被阻塞

如果我想使用單獨的線程來獲得服務器響應,我應該怎麼做?有這種需求的設計模式嗎?

package test.socket; 

import java.io.BufferedReader; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 

public class TestMario { 

    private InputStream in; 
    private OutputStream out; 

    public static void main(String[] args) throws Exception { 

    new TestMario().go(); 
    } 

    public TestMario() { 

    try { 
     Socket echoSocket = new Socket("xxx.xxx.xxx.xxx", 1234); 
     in = echoSocket.getInputStream(); 
     out = echoSocket.getOutputStream(); 

    } catch (UnknownHostException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 

    public void go() throws UnknownHostException, IOException { 

    Thread writer = new Thread(new Runnable() { 

     public void run() { 
     BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
     PrintWriter writer = new PrintWriter(out); 
     String userInput; 
     try { 
      System.out.print("input your command:"); 
      while ((userInput = stdIn.readLine()) != null) { 
      System.out.println("you type:" + userInput); 
      writer.print(userInput); 
      writer.flush(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     } 

    }); 

    Thread reader = new Thread(new Runnable() { 

     StringBuffer sb = new StringBuffer(); 

     public void run() { 

     while (true) { 
      System.out.println("waiting for server response..."); 
      try { 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      byte[] content = new byte[512]; 
      int bytesRead = -1; 
      while((bytesRead = in.read(content)) != -1) { // read() doesn't block anymore after first read 
       baos.write(content, 0, bytesRead); 
      } // while 
      System.out.println("got:" + new String(baos.toByteArray())); 
      } 
      catch (Exception e) { 
      e.printStackTrace(); 
      } 
     } 
     } 

    }); 

    writer.start(); 
    reader.start(); 

    System.out.println(); 
    } 
} 
+3

它是否返回-1? – assylias

+0

你有什麼證據表明它沒有阻止? – EJP

+0

我們可以看到服務器嗎? – Djon

回答

3

這意味着它返回-1或拋出IOException。您實現了2個循環:內部循環驗證讀取返回的值,如果值爲-1,則退出。這可以。然而,外部循環while(true)使您可以一次又一次地輸入讀取,因此不會因爲流結束而被阻塞。

編輯:信貸給@assylias寫評論,提示這一點。

+0

+1結束流到達,沒有外環退出條件 –

+0

@AlexR,謝謝你的迴應。它在第一次成功讀取後總是返回-1,如果發生任何異常,我應該看到異常堆棧打印。如果我每當-1退出「while」循環,我應該如何保持活動連接才能接收服務器推送消息?有什麼建議?非常感謝。 – Matt