Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@kazuki43zoo

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

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

}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?