2013-01-14 67 views
0

我正在構建一個Java客戶端應用程序,它需要向服務器發送消息並在接收到響應後。我可以成功發送消息,問題是我無法獲得響應,因爲在嘗試讀取「BufferedReader」時,我得到一個IO異常(「Socked is closed」)。客戶端應用程序套接字在打印後關閉字符串

這是我的代碼,到目前爲止:

public class MyClass { 

    /** 
    * @param args the command line arguments 
    */ 
    @SuppressWarnings("empty-statement") 
    public static void main(String[] args) { 
     JSONObject j = new JSONObject(); 
     try { 
      j.put("comando", 1); 
      j.put("versao", 1); 
      j.put("senha", "c4ca4238a0b923820dcc509a6f75849b"); 
      j.put("usuario", "1"); 
      j.put("deviceId", "1"); 

     } catch (JSONException ex) { 
      System.out.println("JSON Exception reached"); 
     } 

     String LoginString = "{comando':1,'versao':1,'senha':'c4ca4238a0b923820dcc509a6f75849b','usuario':'1','deviceId':'1'}"; 
     try { 
      BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); 

      Socket clientSocket = new Socket("10.1.1.12", 3333); 
      System.out.println("Connected to the server successfully"); 
      PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(),true); 

      outToServer.println(j.toString()); 
      outToServer.close(); 
      System.out.println("TO SERVER: " + j.toString()); 

      BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

      String resposta = inFromServer.readLine(); 
      System.out.println("FROM SERVER: " + resposta); 

      clientSocket.close(); 
     } catch (UnknownHostException ex) { 
      System.out.println("Could not connect to the server [Unknown exception]"); 
     } catch (IOException ex) { 
      System.out.println(ex.getMessage()); 
     } 
    } 
} 

我知道插座被關閉,因爲的OutToServer.close()但關閉流是發送消息的唯一途徑。我應該如何處理這種情況?

+0

你確定關閉流發送消息的唯一途徑?有flush()方法,甚至沒有必要,因爲您將第二個參數(autoFlush)設置爲true來構建PrintWriter。我無法明白你的觀點。 PS:你有服務器代碼嗎? – gd1

回答

1

嘗試調用outToServer.flush()

這將嘗試從緩存刷新數據,但仍不能保證它會被髮送。

+0

我已經試過了,儘管它沒有奏效。 – blacblu

+1

這是正確的,我仍然指出他正在使用autoFlush = true構造PrintWriter,因此flush()應該在每個println時自動調用。有一些奇怪的事情發生。 blacblu是否嘗試通過打開Telnet會話來測試服務器行爲?你有服務器代碼嗎?有沒有客戶端可以與服務器一起工作?也許你得到一個封閉的套接字,因爲服務器失敗並出現異常。 – gd1

+0

好的。我試圖提取服務器的通信協議,並使用另一臺服務器來測試我的客戶端,我使用.NET來測試我的客戶端的服務器有故障。我關閉它並打開合法的服務器,並得到預期的響應。謝謝 – blacblu

1

flush()並非如此與new PrintWriter(, true)

真正的問題是,您正在關閉PrintWriter outToServer,其中包含InputStream,同樣來自Socket

當您關閉outToServer時,您將關閉整個套接字。您必須使用Socket#shutdownOutput()

如果您想保留套接字的輸入/輸出通道以進一步通信,您甚至不必關閉輸出。

  1. flush()當您完成任何writeXXX。這些writeXXX實際上並不意味着你將這些字節和字符發送到套接字的另一端。

  2. 您可能必須關閉輸出,並且僅輸出以向您發送的所有服務器發送信號,以表示您發送的所有內容必須發送。這實際上是服務器端套接字需求的問題。

final Socket socket = new Socket(...); 
try { 
    final PrintStream out = new PrintStream(socket.getOutputStream()); 
    // write here 
    out.flush(); // this is important. 
    socket.shutdownOutput(); // half closing 

    // socket is still alive 

    // read input here 

} finally { 
    socket.close(); 
} 
+1

+1這很可能就是解決方案。 'shutdownOutput()'將在TCP級別刷新輸出緩衝區。 – gaborsch

+0

@GaborSch感謝您耐心等待[Konglish](http://en.wikipedia.org/wiki/Konglish) –

相關問題