简体   繁体   中英

Netty occasionally generates "Connection reset by peer" exception when client close connection

I am writing a WebSocket server & client with netty .

I have overridden channelInactive & exceptionCaught . The problem is when the clients close the connection, the server occasionally gets java.io.IOException: Connection reset by peer . I have learned that this is caused by the server still reading from the channel which is closed. Does it mean that sometimes the IO of the last message was not finished when channel.close() is called on the client side?

I have tried adding a waiting time between sending the last message and the close action, but the exception still occurred even with a 1 second delay (both server & client run on localhost).

Is there a way to get rid of this, or should I just ignore it?

The code & error message is as follows.

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    wsHolder.remove(ctx);

    List<ChannelHandlerContext> ctxList = wsHolder.getAllUserCtx();
    if (ctxList.size() > 0) {
        for (ChannelHandlerContext octx : ctxList) {
            if (!octx.channel().id().equals(ctx.channel().id())) {
                octx.channel().writeAndFlush(new UserLogout(id));
            }
        }
    }
    super.channelInactive(ctx);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    log.error("Exception in WebsocketInHandler of ctx {}: {}", wsHolder.getUserId(ctx), cause.getMessage());
    log.error("Error:", cause);
    if (!(ctx.channel().isActive() && ctx.channel().isWritable())) {
        ctx.close();
    }
}

Exception message:

java.io.IOException: Connection reset by peer
    at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
    at sun.nio.ch.IOUtil.read(IOUtil.java:192)
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
    at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1133)
    at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

You can just ignore it.

Netty does the shutdown gracefully if you use the right method shutdownGracefully . If you shut down the client by kill -9 pid , then no exception would be seen in the server side. The exception ocurred maybe because you terminated it in the IDE, which means the client was closed ungracefully at once, and the usual handshake process was bypassed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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