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

时间:2015-08-12 09:41:17

标签: proxy netty

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

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

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

1 个答案:

答案 0 :(得分:2)

不确定真正理解你的问题。所以我试着重新制定:

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

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

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

其中:

  • channelOrCtxToFinalServer是从您的Netty代理连接到远程最终服务器的ChannelHandlerContextChannel之一,
  • 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();
                    }
                }
            });
        }
    }
    
  • 最后使用完全相同的逻辑,向客户添加最终确认(当然取决于您的协议):(请参阅herehere

    /**
     * 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);
        }
    }