2011-10-08 71 views
1

我有三個類,客戶端,服務器和處理器(這是將要處理的服務器的連接),正如我在下面:異常與ObjectInputStream的

// The Client 
    public void sendSomePackage() { 
     try { 
      socket = new Socket("localhost", 54321); 
      sos = socket.getOutputStream(); 
      oos = new ObjectOutputStream(sockOutput); 
     } catch (IOException e) { 
      e.printStackTrace(System.err); 
      return; 
     } 

     // About to start reading/writing to/from socket 

     try { 
      Package package = new Package(100); 
      oos.writeObject(pacote); 

     } catch (IOException e) { 
      e.printStackTrace(System.err); 
     } 

     try { 
      Thread.sleep(50); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // Done reading/writing to/from socket, closing socket. 

     try { 
      sock.close(); 
     } catch (IOException e) { 
      System.err.println("Exception closing socket."); 
      e.printStackTrace(System.err); 
     } 
     //Exiting 
    } 

現在服務器類:

// The Server - with a method that just wait for connections 

    public void waitForConnections() { 
     while (true) { 
      try { 
       socket = serverSocket.accept(); 

       // Server:Accepted new socket, creating new handler for it 
       SimpleHandler handler = new SimpleHandler(socket); 
       handler.start(); 

       // Server:Finished with socket, waiting for next connection 
      } 
      catch (IOException e){ 
       e.printStackTrace(System.err); 
      } 
     } 
    } 

我的處理程序,它只是處理服務器的連接:

@Override 
public void run() { 
    //Handler: Handler run() starting 
    while (true) { 
     try { 
      package = (Package) ois.readObject(); 
      if (pacote != null) { 
       System.out.println("Package received " + pacote.getSourceid()); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(System.err); 
      break; 
     } 
    } 

    try { 
     // SimpleHandler:Closing socket 
     sock.close(); 
     ois.close(); 
    } catch (Exception e) { 
     // Handler: Exception while closing socket, e=" + e); 
     e.printStackTrace(System.err); 
    } 

} 

的想法是,客戶端發送一些'包'對象到我的服務器,它將繼續運行,隨時接收'包'對象。 連接工作正常,但在異常啓動的程序的結束,這是一個:

Package received 100 
java.io.EOFException 
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at br.ufscar.socket.SimpleHandler.run(SimpleHandler.java:45) 
    at java.lang.Thread.run(Unknown Source) 

我已經尋找的東西在谷歌,但沒有那麼遠。 有什麼想法?

+0

您是否考慮查找用於EOFException的Javadoc? – EJP

回答

3

這是工作完全按照你想要的(可能)。它讀取100然後再次遍歷循環(while(true)永遠不會停止循環,直到break語句)並拋出異常,因爲沒有更多的數據已經發送,並且它會轉到catch語句並在退出while循環之前打印錯誤。

+3

即使沒有更多的數據要發送,有一些方法可以不啓動任何異常? –

2

EOFException是一個IOException,它指示流的結束。

+0

嗯,我現在得到它,謝謝Xeno –

0

這裏我們說,如果沒有任何更多的字節讀取然後我們嘗試讀取對象之前,應該跳出while循環,等等

while (true) { 
    if (ois.read() == -1) break; 
    //...rest of the code 
} 
+0

你剛扔掉一個字節的輸入。以下readObject()將因此失敗。 – EJP

-1

好吧,這是何等的對象流工作和無處不在的解決方案。

對象流數據前面有一個4字節的「神奇」序列AC ED 00 05。一個ObjectInputStream將在施工時間而不是在第一次閱讀之前查看這些數據。這是合乎邏輯的:在應用程序太遠之前,要確定它是一個合適的流。該序列在構建時由ObjectOutputStream進行緩衝,以便在第一次寫入時將其推入流中。

這種方法會導致緩衝情況或通過套接字傳輸的複雜性。 幸運的是,所有這些問題都有效的解決方案一樣簡單:

施工後立即沖洗ObjectOutputStream

ObjectOutputStream myStream = new ObjectOutputStream (anotherStream); 
myStream.flush(); 
+0

這不會解決EOFException。 – EJP