2

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.

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..

Thanks in advance!

Community
  • 1
  • 1
lhlmgr
  • 2,087
  • 1
  • 22
  • 38
  • 1
    You were given a wrong answer to your previous question. You don't need any of those shutdowns. They don't make the slightest bit of difference in this situation. – user207421 Oct 11 '15 at 23:16

1 Answers1

2

I still have open sockets in TIME_WAIT state on the client side.

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.

The state expires after 2*MSL, which means two maximum segment lifetimes, which means two times two minutes.

There is no problem here to solve.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks for your direct answer and informative answer. Alright, so i'm going to stop fumble with my code to resolve this "issue". A colleague told me, he solved this issue with NIO1. Anyway, thanks for the clarification! – lhlmgr Oct 11 '15 at 23:23
  • 2
    You can move this 'issue' to the peer, and you've already done that by ensuring that the client closes first, which moves it to the client, which is where you want it. You can't 'solve' this 'issue', as it isn't an 'issue' to 'solve': it's a defined behaviour of TCP, and it is there for a good reason. – user207421 Oct 11 '15 at 23:26
  • just another short (side) question. Since i have ~56k sockets in TIME_WAIT state, makes it sense, to build a socketpool with asynchronous SocketChannels? – lhlmgr Oct 12 '15 at 12:26