为什么当客户端被 SIGKILL 杀死时,服务器上的 channelInactive 被调用?

Why channelInactive on server is called when the client is killed by SIGKILL?

有一个回显服务器和一个回显客户端。当我使用 kill -9 <client_pid> 终止客户端进程时,服务器上的 channelInactive 被调用。

客户端被SIGKILL杀死了,所以应该来不及主动关闭这个socket。因此,不应触发服务器上的 channelInactive,但确实发生了。

为什么当客户端被SIGKILL杀死时调用服务器上的channelInactive

EchoServer class


public class EchoServer {
  private final int port;

  public EchoServer(int port) {
    this.port = port;
  }

  public static void main(String[] args) throws InterruptedException {
    int port = 9001;
    new EchoServer(port).start();
  }

  public void start() throws InterruptedException {
    EventLoopGroup group = new NioEventLoopGroup();

    try {
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap
          .group(group)
          .channel(NioServerSocketChannel.class)
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
              ch.pipeline()
                .addLast(new ChannelInboundHandlerAdapter() {
                  @Override
                  public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                    System.out.println("channelInactive()");
                  }
                });
            }
          });

      ChannelFuture future = bootstrap.bind(new InetSocketAddress(port)).sync();
      future.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully().sync();
    }
  }
}

EchoClient class


public class EchoClient {
  private final String host;
  private final int port;

  public EchoClient(String host, int port) {
    this.host = host;
    this.port = port;
  }

  public void start() throws InterruptedException {
    EventLoopGroup group = new NioEventLoopGroup();
    try {
      Bootstrap bootstrap = new Bootstrap();
      bootstrap
          .group(group)
          .channel(NioSocketChannel.class)
          .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
            }
          });

      ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)).sync();
      future.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully().sync();
    }
  }

  public static void main(String[] args) throws InterruptedException {
    new EchoClient("localhost", 9001).start();
  }
}

The client is killed by SIGKILL, so it should have no time to actively close this socket.

客户端应用程序没有主动关闭套接字。如果没有本地应用程序打开套接字,客户端 OS 内核会隐式关闭套接字。