获取java.io.IOException:在客户端服务器Java套接字程序中激活流

时间:2011-08-31 19:11:50

标签: java sockets stream ioexception

在我发布这篇文章之前,我查看过一些关于此例外的问题,但找不到确切的答案。

我有一个客户端服务器应用程序,它基本上是一个与TCP连接的套接字程序。 在运行正常一段时间之后,我从客户端获得了这个例外。但是,即使它抛出异常,客户端也会向服务器发送数据。(可能是因为Event对象连续传递)。但是服务器在接收数据时工作正常。我在发送数据时从客户端获得的异常是

java.io.IOException: stream active ..这发生在下面代码中提到的“LINE 01”中。

这是我使用的客户端代码。

        // And "Event" objects are passed continuously to this method one by one.              

         SocketChannel socketChannel = null;

        try {

        socketChannel = SocketChannel.open(new InetSocketAddress(host, port));
        oos = new ObjectOutputStream(socketChannel.socket().getOutputStream());
        oos.reset(); -----------> LINE 01
        oos.writeObject(event); 

    } catch (IOException e) {
        throw new RuntimeException(e);
    }

这是服务器代码

    ServerSocketChannel serverSocketChannel = null;
    try {
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));

        SocketChannel socket = serverSocketChannel.accept();
        ObjectInputStream ois = new ObjectInputStream(socket.socket().getInputStream());
         do {
                  Object object = ois.readObject();
                  if(object instanceof Event) {
                      Event event = (Event)object ;
                      viewDetailsInUI(event);
                  }

           } while (true);

这是我从客户端获得的堆栈跟踪。

java.io.IOException: stream active
    at java.io.ObjectOutputStream.reset(ObjectOutputStream.java:478)
    at org.demo.siddhi.server.EventSenderClient.sendEventToSubscriber(EventSenderClient.java:42)
    at org.demo.siddhi.server.query.types.SimpleStockQuoteVWAPQueryProvider$3.callBack(SimpleStockQuoteVWAPQueryProvider.java:344)
    at org.siddhi.core.OutputStreamHandler.run(OutputStreamHandler.java:61)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

任何人都可以解释为什么会这样?

3 个答案:

答案 0 :(得分:4)

这里有几个问题。

  1. 正如Peter Lawrey指出的那样,立即调用reset()构建ObjectOutputStream是完全没有意义的,而且可能是非法的。删除它。

  2. 您正在通过流在阻止模式下使用SocketChannel,即您在两种情况下都只使用底层套接字。使用SocketServerSocket会更好。它更简单,更清晰。

  3. 您的服务器循环读取多个对象的ObjectInputStream,但您的客户端创建一个新连接,发送一个对象,然后(我希望)关闭它。这些不加起来。 要么你的客户端应该保存TCP连接和ObjectOutputStream并使用它来编写多个对象,在这种情况下你可能需要在 writeObject()之后调用reset(),并且当服务器获得EOFException时,服务器需要突破循环,服务器可以在读取一个对象后关闭其连接,并且不需要while(true)循环。

答案 1 :(得分:3)

它似乎相信它已经在序列化一个对象。

  

IOException如果在序列化对象时调用reset()。

您无需在开始时调用reset(),因为没有任何重置()。我会放弃它,它可能会正常工作。

如果要定期调用reset,可以在writeObject()之后调用它。

当缓冲流时,你也应该在某处调用flush()。

答案 2 :(得分:1)

查看OOS代码:

 493 if (depth != 0) {
 494               throw new IOException("stream active");
 495           }