【问题标题】:Sending TCP packets via Netty, Netty is dividing the data into different packets?通过Netty发送TCP数据包,Netty是把数据分成不同的数据包?
【发布时间】:2013-08-27 12:30:58
【问题描述】:

我目前正在使用 Netty 4.0.7.Final 编写一个通过 TCP 接收图像(大小:~10k)的服务器。 我修改了 Netty 的示例回显客户端处理程序,只将文件读入字节,然后将其发送到我的 Netty 服务器。

public EchoClientHandler(int firstMessageSize) throws IOException {
    File image = new File("google.jpeg");
    byte[] imageBytes = FileUtils.readFileToByteArray(image);
    byte[] bytes = Base64.encodeBase64(imageBytes);
    String base64 = new String(bytes);
    //System.out.println("base64="+ base64);
    firstMessage = Unpooled.copiedBuffer(base64, CharsetUtil.UTF_8);
}

我的测试图像是 9k,我可以看到整个图像正在通过 Netty 日志记录发送

io.netty.handler.logging.LoggingHandler logMessage
INFO: [id: 0x132baef0, /127.0.0.1:49710 => localhost/127.0.0.1:2112] WRITE(11964B)

但是,Netty服务器接收到消息的时候,好像是把消息分成了两个包,第一个包是1024字节,第二个包是10940字节,加起来就是1024+10940=11964字节(图像的总大小)

2013-08-24 22:56:33,700 [nioEventLoopGroup-3-1] INFO  MessageDecoder - capacity = 1024
2013-08-24 22:56:33,700 [nioEventLoopGroup-3-1] INFO  MessageDecoder - readable bytes = 1024
2013-08-24 22:56:33,709 [nioEventLoopGroup-3-1] INFO  MessageDecoder - capacity = 16384
2013-08-24 22:56:33,710 [nioEventLoopGroup-3-1] INFO  MessageDecoder - readable bytes = 10940

这是我的解码器的样子(虽然我怀疑解码器与它有什么关系,但看起来 Netty 甚至在它到达解码器之前就已经处理了)

public class MessageDecoder extends ByteToMessageDecoder {

private static final Logger LOGGER = LoggerFactory.getLogger(MessageDecoder.class);

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    // Convert to String first
    LOGGER.info("capacity = " + in.capacity());
    LOGGER.info("readable bytes = " + in.readableBytes());
    String rawString = in.readBytes(in.readableBytes()).toString(CharsetUtil.UTF_8);    
    LOGGER.info("Received base64 String={}", rawString);
}

我也尝试过大量文件,看起来 Netty 总是将消息分成 1024 字节的数据包 + 文件其余部分的大小??

我想知道为什么 Netty 会这样做?有没有办法一次性获取完整的数据包?

非常感谢。

【问题讨论】:

  • 我不认为 N​​etty 正在这样做。这与 tcp/ip 的工作方式有关。这取决于您的消息通过哪些路由器。例如,MTU(最大传输单元)在任何 WLAN 上约为 1400 字节。
  • Netty 不会对任何东西进行分段,但 IP 和 TCP 会。
  • 非常感谢,我能够使用 DelimiterBasedFrameDecoder(Netty 附带)解决并指定最大帧大小

标签: java sockets networking tcp netty


【解决方案1】:

如果您想从处理程序中抽象出碎片,您需要为您的消息构建框架。这可以通过在发送时使用LengthFieldPrepender 和在接收时使用LengthFieldBasedFrameDecoder 轻松完成。这可确保您的消息解码器只看到表示完整消息的字节缓冲区。

请注意,您的帧处理程序应位于 ChannelPipeline 的首位,除非您还使用 SSL 处理程序和/或压缩处理程序,在这种情况下 SSL 应位于首位,然后是压缩,然后是帧处理程序。在管道中排在第一位意味着处理程序将首先处理入站事件,最后处理出站事件。

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2010-10-20
    • 2015-07-23
    • 1970-01-01
    • 2021-09-23
    • 2013-09-16
    相关资源
    最近更新 更多