简体   繁体   English

带有正常关机功能的AsynchronousServerSocketChannel

[英]AsynchronousServerSocketChannel with graceful shutdown

In my previous Question i asked how to implement a correct Multithreaded server. 我之前的问题中,我问过如何实现正确的多线程服务器。 I got the response to program a "graceful shutdown", and i tried todo so. 我收到了对程序“正常关机”的响应,并且我尝试这样做。 However, it didn't work. 但是,它没有用。 I still have open sockets in TIME_WAIT state on the client side. 我在客户端仍处于TIME_WAIT状态的开放套接字。

Client: 客户:

private <T extends Serializable> T sendCommand(final Command<T> command) throws ExecutionException, InterruptedException, IOException, ClassNotFoundException {
    T result = null;

    try (final AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(channelGroup)) {
        channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
        channel.connect(this.mwInfo.getNextMiddleware()).get();

        final OutputStream os = Channels.newOutputStream(channel);
        final InputStream is = Channels.newInputStream(channel);
        final ObjectOutputStream oos = new ObjectOutputStream(os);

        oos.writeObject(command);
        oos.flush();
        channel.shutdownOutput();

        final ObjectInputStream ois = new ObjectInputStream(is);
        result = (T) ois.readObject();

        while(ois.read() != -1){
            System.out.println("busy");
        }

        try{
            channel.shutdownInput();
        }catch(Exception ex){
            ex.printStackTrace();
        }

        oos.close();
        ois.close();
    }

    return result;
}

Server: 服务器:

this.asyncSocket.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
        @Override
        public void completed(final AsynchronousSocketChannel result, Void attachment) {
            asyncSocket.accept(null, this);

            exec.submit(new Runnable() {
                @Override
                public void run() {
                    Command cmd = null;
                    ObjectInputStream ois = null;
                    ObjectOutputStream oos = null;

                    try {
                        ois = new ObjectInputStream(Channels.newInputStream(result));
                        cmd = (Command) ois.readObject();

                        while(ois.read() != -1){
                            System.out.println("busy");
                        }

                        result.shutdownInput();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }

                    try{
                        oos = new ObjectOutputStream(Channels.newOutputStream(result));
                        oos.writeObject("test"); //do some other work here..
                        oos.flush();
                        result.shutdownOutput();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    try {
                        oos.close();
                        ois.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    try {
                        result.close();
                    }catch (IOException ex){
                        ex.printStackTrace();
                    }
                }
            });
        }

        @Override
        public void failed(Throwable exc, Void attachment) {
        }
    });

Does anybody know why this isn't a graceful shutdown? 有人知道为什么这不是正常关机吗? It doesn't look well structured, since i was playing with the try-catch blocks.. 由于我正在使用try-catch块,因此它的结构看起来不太好。

Thanks in advance! 提前致谢!

I still have open sockets in TIME_WAIT state on the client side. 我在客户端仍处于TIME_WAIT状态的开放套接字。

You will always have sockets in TIME_WAIT on one side or the other, and the client side is where you want them, not the server side. 您总是会在一侧或另一侧的TIME_WAIT拥有套接字,而客户端是您需要套接字的地方,而不是服务器端。

The state expires after 2*MSL, which means two maximum segment lifetimes, which means two times two minutes. 该状态在2 * MSL之后过期,这意味着两个最大段生存期,这意味着两次两分钟。

There is no problem here to solve. 这里没有问题可以解决。

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

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