2016-01-17 61 views
2

我正在創建一個Java客戶端程序,它向服務器發送一個命令,服務器發回一個確認和一個響應字符串。TCP/IP客戶端:從服務器讀取多個輸入流的最佳方式

的響應被以這種方式發送回

客戶端 - >服務器:cmd_string

服務器 - >客戶端:ack_msg(06)

服務器 - >客戶端:response_msg

當我嘗試讀取輸入時,要麼只能讀取只讀取帶有一個輸入流的確認消息

我的客戶端程序能夠以某種方式讀取消息(hacky方法)。要閱讀輸入,我必須使用Bufferedreader閱讀ack msg。

  1. 在只能夠讀取ack_msg不是以下MSG
  2. DataInputStream類代碼此緩衝讀取器是需要的讀取響應味精。
  3. 如果我跳過第1步,只是使用Datainputstream,我無法讀取完整的消息。

Client.java

try { 
      Socket clientSocket = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);// ip,port 

      System.out.println(" client Socket created .. "); 

      PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true); 

      String ToServer = command; 
      outToServer.println(ToServer); 

      in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
//   
      // while (!in.ready()) { 
      // } 
      System.out.println(in.read()); // Read one line and output it 


      // === 
      byte[] messageByte = new byte[1000];//assuming msg size -need to know eact msg size ? 
      boolean end = false; 
      String dataString = ""; 
      int bytesRead = 0; 

      try { 
       DataInputStream in1 = new DataInputStream(clientSocket.getInputStream()); 
// 
       while (!end) { 
        bytesRead = in1.read(messageByte); 
        dataString += new String(messageByte, 0, bytesRead); 
        if (dataString.length() > 0) { 
         end = true; 
        } 
       } 
       System.out.println("MESSAGE: " + dataString); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      // === 

      in.close();    

      clientSocket.close(); 
      System.out.print("connection closed"); 

     } catch (Exception e) { 
      System.out.print("Whoops! It didn't work!\n"); 
      e.printStackTrace(); 
     } 

輸出

客戶端套接字創建..

響應:6

MESSAGE:³CO³0³Œ

連不上

當我跳過步驟1

客戶端的Socket創建..

留言: -

連接關閉

我如何編寫代碼讀取所有來自 服務器的輸入(確認msg &響應消息&它還應該檢查 數據的大小並據此讀取)?

簡稱How to read all of Inputstream in Server Socket JAVA

由於

回答

1

這些語句強制關閉該流只要至少1個字節被髮送。

dataString += new String(messageByte, 0, bytesRead); 
if (dataString.length() > 0) { 
    end = true; 
} 

只要收到6的確認,連接就會關閉。如果ack被忽略,則響應可能以多個數據包發送,接收到第一個數據包後連接將關閉。

您必須能夠確定確認和響應何時結束。

  1. 如果您知道確認和響應中有多少個字符,則可以像您提到的問題那樣循環。你需要一個循環來確認答案,一個答覆。
  2. 如果你不知道的 字符數,那麼你將不得不尋找特殊字符,如文件結束, 結束線或知道當ACK線結束,當 服務器響應結束。爲每封郵件的末尾尋找特殊字符。
  3. 第三種可能性是等待 特定時間。當時間到期時,繼續。這在TCP上不可靠,因爲數據可能會丟失並重新發送。這可能需要比分配迴應更多的時間。 我同意下面的評論。本來,我猶豫在列表中加3。該選項很可能用於檢測通信通道的問題。如果時間到期,那麼客戶會放棄一個錯誤條件,它不會繼續處理,就好像一切都好。
+1

我只是從這個答案中刪除(3)。這真的不行。您無法預測服務器的延遲或服務時間。 – EJP

2

您不能在同一底層套接字上同時使用BufferedReader和DataInputStream。你會在BufferedReader中丟失數據。使用相同的流或閱讀器來處理所有事情,以及套接字的使用。同上作家和輸出流。

相關問題