Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过Netty发送TCP数据包,Netty将数据分为不同的数据包?_Java_Sockets_Networking_Tcp_Netty - Fatal编程技术网

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

Java 通过Netty发送TCP数据包,Netty将数据分为不同的数据包?,java,sockets,networking,tcp,netty,Java,Sockets,Networking,Tcp,Netty,我目前正在使用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.read

我目前正在使用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字节(图像的总大小)

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

公共类MessageDecoder扩展为ByteToMessageDecoder{
私有静态最终记录器Logger=LoggerFactory.getLogger(MessageDecoder.class);
@凌驾
受保护的无效解码(ChannelHandlerContext ctx、ByteBuf输入、列表输出)引发异常{
//先转换为字符串
LOGGER.info(“capacity=“+in.capacity());
LOGGER.info(“readable bytes=“+in.readableBytes());
String rawString=in.readBytes(in.readableBytes()).toString(CharsetUtil.UTF_8);
info(“接收到的base64字符串={}”,rawString);
}
我还尝试了大量的文件,看起来Netty总是将消息分成1024字节的数据包+文件其余部分的大小

我想知道Netty为什么要这么做?有没有一种方法可以一次性获得完整的数据包?


非常感谢。

如果您想从处理程序中提取碎片,则需要对消息进行帧处理。这可以通过使用“发送时”和“接收时”轻松完成。这确保消息解码器只看到表示完整消息的字节缓冲区


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

我认为Netty没有这样做。这与tcp/ip的工作方式有关。这取决于您的消息通过的路由器。例如MTU(最大传输单位)在任何WLAN上大约是1400字节。Netty不会分割任何内容,但IP和TCP会。非常感谢,我能够使用DelimiterBaseFrameDecoder(Netty附带)解析并指定最大帧大小
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
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);
}