简体   繁体   English

通过Netty发送TCP数据包,Netty是否将数据分为不同的数据包?

[英]Sending TCP packets via Netty, Netty is dividing the data into different packets?

I'm currently using Netty 4.0.7.Final to write a server that receives images (size: ~10k) over TCP. 我目前正在使用Netty 4.0.7.Final编写一个通过TCP接收图像(大小:〜10k)的服务器。 I modified Netty's sample echo client handler to just read a file into bytes, and send it over to my Netty server. 我修改了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);
}

My test image is 9k, and I can see the whole image is being sent via Netty logging 我的测试映像是9k,我可以看到整个映像都是通过Netty日志发送的

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

However, when the Netty server receives the message, it seems to be dividing the message into two packets, the first packet is 1024 bytes, and the second one is 10940 bytes, which adds up to 1024+10940 = 11964 bytes (total size of the image) 但是,当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

Here's what my decoder looks like (although I doubt the decoder has anything to do with it, it looks like Netty is handling this before it even reaches the decoder) 这是我的解码器的外观(尽管我怀疑解码器与它有什么关系,但看起来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);
}

I also tried large number of files, it looks Netty is always dividing a message into packets of 1024 bytes + whatever size for the rest of the file?? 我还尝试了大量文件,看来Netty总是将一条消息分成1024字节的数据包+其余文件的大小如何?

I'm wondering why Netty is doing this ? 我想知道为什么Netty会这样做吗? And is there a way to just get the complete packet in one-go? 有没有办法一次性获得完整的数据包?

Thanks so much. 非常感谢。

If you'd like to abstract fragmentation from your handler you need to frame your messages. 如果您想从处理程序中提取碎片,则需要对消息进行框架化。 This can be done easily by making use of the LengthFieldPrepender when sending and the LengthFieldBasedFrameDecoder when receiving. 这可以很容易地通过利用来完成LengthFieldPrepender发送时和LengthFieldBasedFrameDecoder接收时。 This ensures that your message decoder only sees a byte buffer representing a full message. 这样可以确保您的消息解码器仅看到代表完整消息的字节缓冲区。

Note that your frame handlers should be first in your ChannelPipeline except when you are also using an SSL handler and/or compression handler in which case SSL should be first, followed by compression, followed by the frame handlers. 请注意,除非同时使用SSL处理程序和/或压缩处理程序,否则您的帧处理程序应首先位于ChannelPipeline中,在这种情况下,应首先使用SSL,然后是压缩,然后是帧处理程序。 Being first in the pipeline means that a handler will be first to handle and inbound event and last to handle an outbound event. 在管道中处于第一个位置意味着处理程序将首先处理入站事件,最后处理出站事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM