简体   繁体   English

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

[英]Getting java.io.IOException: stream active in a client server Java socket program

Before I post this I looked at some past questions on this exceptions but couldn't find an exact answar. 在我发布这篇文章之前,我查看了有关此例外的一些过去的问题,但找不到确切的答案。

I have a client server app which is basically a socket program connects with TCP. 我有一个客户端服务器应用程序,它基本上是一个连接TCP的套接字程序。 I got this Exceptions from client side after it runs fine for some time. 在运行正常一段时间之后,我从客户端获得了这个例外。 But still, the client is sending data to the server even though it throws Exceptions.( may be as Event objects are passed continuously). 但是,即使它抛出异常,客户端也会向服务器发送数据。(可能是因为Event对象连续传递)。 But the server works fine as it receives the data. 但是服务器在接收数据时工作正常。 The Exception I get from the client side while sending data is 我在发送数据时从客户端获得的异常是

java.io.IOException: stream active .. This occurs from the "LINE 01" as mentioned in the code below. java.io.IOException: stream active ..这发生在下面代码中提到的“LINE 01”中。

Here is the client code I used. 这是我使用的客户端代码。

        // 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);
    }

Here is the server code 这是服务器代码

    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);

Here is the stack trace I got from the client side. 这是我从客户端获得的堆栈跟踪。

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)

Can anyone please explain why is this ? 任何人都可以解释为什么这个?

There are several problems here. 这里有几个问题。

  1. As Peter Lawrey has pointed out, calling reset() immediately you have constructed the ObjectOutputStream is completely pointless, and probably illegal. 正如Peter Lawrey指出的那样,立即调用reset()构建ObjectOutputStream是完全没有意义的,而且可能是非法的。 Remove it. 去掉它。

  2. You are using SocketChannels in blocking mode via streams, ie you are just using the underlying Sockets in both cases. 您正在通过流在阻塞模式下使用SocketChannel,即您只是在两种情况下都使用底层套接字。 You would be much better off using a Socket and a ServerSocket . 使用SocketServerSocket会好得多。 It's a lot simpler and clearer. 它更简单,更清晰。

  3. Your server loops reading an ObjectInputStream for multiple objects, but your client creates a new connection, sends one object, and then (I hope) closes it. 您的服务器循环读取多个对象的ObjectInputStream,但您的客户端创建一个新连接,发送一个对象,然后(我希望)关闭它。 These do not add up. 这些不加起来。 Either your client should conserve the TCP connection and the ObjectOutputStream and use it to write multiple objects, in which case you may need to call reset() after writeObject(), and the server needs to break out of the loop when it gets EOFException, or your server can close its connection after reading one object, and the while (true) loop is unnecessary. 无论你的客户应该保存的TCP连接,并用ObjectOutputStream,并用它来写多个对象,在这种情况下,你可能需要的writeObject() 之后调用reset(),并且服务器需要打出来的循环当它变得EOFException类, 或者您的服务器在读取一个对象后可以关闭其连接,并且不需要while(true)循环。

It appears to believe it is serializing an object already. 它似乎相信它已经在序列化一个对象。

IOException if reset() is invoked while serializing an object. IOException如果在序列化对象时调用reset()。

You don't need to call reset() at the start as there is nothing to reset(). 您无需在开始时调用reset(),因为没有任何重置()。 I would drop it and it may work fine. 我会放弃它,它可能工作正常。

If you want to call reset regularly, you can call it after writeObject(). 如果要定期调用reset,可以在writeObject()之后调用它。

You should also call flush() somewhere as the stream is buffered. 您还应该在缓冲流时调用flush()。

Look to OOS code: 查看OOS代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM