6

我正在使用 Netty 版本 2.6.0.Final。

如果我正确理解 Netty 文档,在 Channel 上调用 disconnect() 应该允许我稍后调用 connect() 再次连接。但是,当我调用 disconnect() 时,我的 SimpleChannelHandler 子类的 channelDisconnected() 和 channelClosed() 都会被调用。

我在调试模式下打开它,基本上事件的顺序是:

  1. 我在我的频道上调用 disconnect()
  2. Channels.disconnect() 被调用:

    public static ChannelFuture disconnect(Channel channel) {
      ChannelFuture future = future(channel);
      channel.getPipeline().sendDownstream(new DownstreamChannelStateEvent(
            channel, future, ChannelState.CONNECTED, null));
      return future;
    }
    
  3. 最终,NioSocketPipelineSink.eventSunk() 被调用,相关部分是:

        case CONNECTED:
            if (value != null) {
                connect(channel, future, (SocketAddress) value);
            } else {
                channel.worker.close(channel, future);
            }
            break;
    

因此,由于值为 null 并且状态为 CONNECTED,因此通道将关闭(尽管根据此处CONNECTED 与 null 应该表示断开连接的请求,不一定关闭。

那么我在这里错过了什么吗?如果 disconnect() 只是导致通道被关闭,那么它有什么意义呢?

这不是一个大问题,因为如果我需要,我可以为我的情况创建一个新通道,但从最初的检查来看,这似乎是一个 Netty 错误,除非我只是误解了它应该如何工作或者我'我在做一些傻事。

4

1 回答 1

8

Netty 的一个目的是提供一个统一的 Channel 抽象,无论底层实现是 OIO、NIO 还是 AIO,它对于面向连接的套接字 (TCP) 和无连接套接字 (UDP) 的工作方式大致相同。由于存在很多差异,统一接口对于特定实现的某些部分看起来会有些奇怪。

断开 TCP 套接字的行为意味着关闭它(至少从 Java API 的角度来看)。但是断开一个 UDP 套接字并不意味着关闭它,只是删除了本地 ip 地址/端口和远程 ip 地址/端口之间的关联。

所以,不,你没有做任何愚蠢的事情,但我建议改为对 OPEN/CLOSE 事件采取行动,除非你真的需要在其生命周期内将 UDP 套接字“连接”到不同的远程目标。

编辑:在前一段中错过了一个重要的“不”。

于 2013-01-02T22:56:08.983 回答