我目前正在使用 Netty 4.0.7.Final 编写一个通过 TCP 接收图像(大小:~10k)的服务器。 我修改了 Netty 的示例 echo 客户端处理程序,将文件读取为字节,然后将其发送到我的 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 为什么要这样做?有没有办法一次性获取完整的数据包?
非常感谢。
最佳答案
如果您想从处理程序中提取碎片,您需要构建消息。这可以通过使用 LengthFieldPrepender
轻松完成。发送时和 LengthFieldBasedFrameDecoder
接收时。这可确保您的消息解码器仅看到代表完整消息的字节缓冲区。
请注意,您的帧处理程序应位于 ChannelPipeline
中的第一个位置,除非您还使用 SSL 处理程序和/或压缩处理程序,在这种情况下,SSL 应位于第一个,然后是压缩,最后是帧处理程序。成为管道中的第一个意味着处理程序将首先处理入站事件,最后处理出站事件。
关于java - 通过Netty发送TCP数据包,Netty是将数据分成不同的数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18420049/