1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NettyでFINとRSTを動的に切り替える方法

Posted at

Nettyを使ってサーバを構築する際に、Channel(ソケット)をcloseする際に状況によってFINとRSTを使い分けたい場合があります。例えば、正常時はFIN(遅延タイムアウト時はRST)だけど、異常を検知した際は直ちにRSTにするような要件がある場合です。

close時のデフォルト動作の指定

Channelをcloseした際のFIN/RSTのどちらを使用するかは、ServerBootstrapを構築する際に指定することができます。

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(0);
ServerBootstrap bootstrap = new ServerBootstrap()
    .option(ChannelOption.SO_BACKLOG, 1024)
    .group(bossGroup, workerGroup)
    .channel(NioServerSocketChannel.class)
    .childOption(ChannelOption.SO_LINGER, 10) // FIN → 遅延タイムアウト(10秒) → RSTでcloseするための指定
    .childHandler(new MyChannelInitializer());
// ...

NOTE:

-1を指定するRSTによる解放は無効化されます。

close時にFIN/RSTを選択

ServerBootstrap構築時に指定したデフォルト動作と異なる方法でcloseしたい場合は、ChannelからChannelConfigを取得してSO_LINGERの設定値を変更することで実現することができます。

@ChannelHandler.Sharable
class MyHandler extends SimpleChannelInboundHandler<byte[]> {
  @Override
  protected void channelRead0(ChannelHandlerContext ctx, byte[] msg) {
    // ...
  }
  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    ctx.channel().config().setOption(ChannelOption.SO_LINGER, 0); // 直ちにRSTでcloseするように指定
    ctx.close();
  }

}
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?