2011-10-08 41 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