【问题标题】:Netty occasionally generates "Connection reset by peer" exception when client close connection客户端关闭连接时,Netty 偶尔会产生“Connection reset by peer”异常
【发布时间】:2022-11-29 09:28:28
【问题描述】:

我正在使用 netty 编写 WebSocket 服务器和客户端。

我已经覆盖了channelInactive & exceptionCaught。问题是当客户端关闭连接时,服务器偶尔会收到java.io.IOException: Connection reset by peer。我了解到这是由于服务器仍在从关闭的通道读取数据造成的。是不是说在客户端调用channel.close()的时候,有时最后一条消息的IO还没有完成呢?

我尝试在发送最后一条消息和关闭操作之间添加一个等待时间,但即使有 1 秒的延迟(服务器和客户端都在本地主机上运行),异常仍然发生。

有没有办法摆脱它,或者我应该忽略它?

代码和报错信息如下。

@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();
    }
}

异常信息:

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)

【问题讨论】:

  • AFAIK,这是正常行为。

标签: java networking websocket netty


【解决方案1】:

你可以忽略它。

如果您使用正确的方法shutdownGracefully,Netty 会优雅地关闭。如果你通过kill -9 pid关闭客户端,那么在服务器端不会看到异常。出现这个异常可能是因为你在IDE中终止了,也就是说客户端一下子被非正常的关闭了,正常的握手过程被绕过了。

【讨论】:

    猜你喜欢
    • 2012-01-18
    • 2014-04-04
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多