在 Netty 中阻止 tcp 数据包接收 4.x

Blocking tcp packet receiving in Netty 4.x

如何在 netty 4.x 中阻止 netty 向客户端发送 ACK 响应?

我试图在 netty 中控制 TCP 数据包接收速度,以便将这些数据包转发到另一台服务器。 Netty 立即收到所有客户端数据包,但 netty 需要更多时间将它们发送出去,所以客户端发送给 netty 后认为它已完成。

所以,我想知道如何在netty转发之前接收到的数据包到另一台服务器时阻止接收到的数据包。

不确定是否真正理解您的问题。所以我尝试重新表述:

  • 我想您的 Netty 服务器充当客户端和另一台服务器之间的代理。
  • 我想你想要做的是只有当你真正将转发的数据包发送到最终服务器(不一定由最终服务器接收,但至少由 Netty 代理发送)时,才将 ack 发送回客户端).

如果是这样,那么你应该使用转发包的未来响应ack,如(伪代码):

channelOrCtxToFinalServer.writeAndFlush(packetToForward).addListener(new ChannelFutureListener() {
  public void operationComplete(ChannelFuture future) {
    // Perform Ack write back
    ctxOfClientChannel.writeAndFlush(AckPacket);
  }
});

其中:

  • channelOrCtxToFinalServerChannelHandlerContextChannel 之一,从您的 Netty 代理连接到您的远程最终服务器,
  • ctxOfClientChannel 是来自您的 Netty 处理程序的当前 ChannelHandlerContext,它在 public void channelRead(ChannelHandlerContext ctxOfClientChannel, Object packetToForward) 方法中从客户端接收数据包。

编辑: 对于大文件传输问题,您可以查看代理示例 here.

尤其要注意以下几点:

  • 同理,注意从客户端一个接一个地接收数据:

    yourServerBootstrap..childOption(ChannelOption.AUTO_READ, false);
    // Allow to control one by one the speed of reception of client's packets
    
  • 在您的前端处理程序中:

    public void channelRead(final ChannelHandlerContext ctx, Object msg) {
        if (outboundChannel.isActive()) {
            outboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) {
                    if (future.isSuccess()) {
                        // was able to flush out data, start to read the next chunk
                        ctx.channel().read();
                    } else {
                        future.channel().close();
                    }
                }
            });
        }
    }
    
  • 最后使用完全相同的逻辑向您的客户端添加最终确认(确认当然取决于您的协议):(参见 here and here

    /**
     * Closes the specified channel after all queued write requests are flushed.
     */
    static void closeOnFlush(Channel ch) {
        if (ch.isActive()) {
            ch.writeAndFlush(AckPacket).addListener(ChannelFutureListener.CLOSE);
        }
    }