Склейка ByteBuf'ов netty

226
29 августа 2018, 08:00

Если я пишу длинный запрос на сервер, к примеру 5000 байтов, то приходит только 1024, а потом приходит остальная часть.

Один человек мне написал, что байты делятся на чанки, чтобы не было OutOfMemory. На другом форуме мне сказали нужно читать все байты, если их не хватает то дочитывать остальные, я пытался сделать, но в голову прилетел тапок, на подошве которого было написано: "Не так читаешь, лови стактрейс на 100500 символов"

Думал может уже есть готовые решения, но в инете ничего не нашёл, кроме ChunkedWriteHandler, но он ничего не сделал.

Написал полностью чистый клиент-сервер, на 2х пакетах, InMessage & OutMessage. Вот что происходит без склейки:

io.netty.handler.codec.DecoderException: org.whileinside.nettyTests.exceptions.BadPacket: Couldn't read packet: 0. Cause: readerIndex(6) + length(5000) exceeds writerIndex(1024): PooledUnsafeDirectByteBuf(ridx: 6, widx: 1024, cap: 1024)

Далее влетает ещё одна ошибка

io.netty.handler.codec.DecoderException: org.whileinside.nettyTests.exceptions.BadPacket: Unknown packet id: 12597

Надеюсь мне кто-нибудь поможет =)

Edit 1: Код

Запуск клиента

Bootstrap b = new Bootstrap()
    .option(ChannelOption.TCP_NODELAY, true)
    .channel(NioSocketChannel.class)
    .group(worker = new NioEventLoopGroup(2))
    .handler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline()
                    .addLast("packetDecoder", new PacketDecoder())
                    .addLast("packetEncoder", new PacketEncoder())
                    .addLast("chunkedWrite", new ChunkedWriteHandler())
                    .addLast("handler", new ClientHandler());
        }
    });
ChannelFuture future = b.connect("127.0.0.1", 2345).sync();
if (future.isSuccess()) {
    System.out.println("Successfully started!");
}
future.channel().closeFuture();

Запуск сервера

ServerBootstrap b = new ServerBootstrap()
    .childOption(ChannelOption.TCP_NODELAY, true)
    .channel(NioServerSocketChannel.class)
    .group(worker = new NioEventLoopGroup(2))
    .childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline()
                    .addLast("packetDecoder", new PacketDecoder())
                    .addLast("packetEncoder", new PacketEncoder())
                    .addLast("chunkedWrite", new ChunkedWriteHandler())
                    .addLast("handler", new ServerHandler());
        }
    });
ChannelFuture future = b.bind("127.0.0.1", 2345).sync();
future.channel().closeFuture();

PacketEncoder & PacketDecoder

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    PacketBuffer buffer = new PacketBuffer(in);
    while(buffer.isReadable()) {
        out.add(PacketManager.readPacket(new PacketBuffer(in)));
    }
}
@Override
protected void encode(ChannelHandlerContext ctx, Packet msg, ByteBuf out) throws Exception {
    PacketBuffer buffer = new PacketBuffer(out);
    out.writeShort(PacketArray.getPacketID(msg.getClass()));
    msg.write(buffer);
}

PacketManager::readPacket

public static Packet readPacket(PacketBuffer buf) {
    short id = buf.readShort();
    if(!PacketArray.containsPacket(id)) {
        throw new BadPacket("Unknown packet id: " + id);
    }
    try {
        Packet packet = PacketArray.searchPacket(id);
        packet.read(buf);
        return packet;
    } catch(Exception e) {
        throw new BadPacket("Couldn't read packet: " + id + ". Cause: " + e.getMessage());
    }
}
READ ALSO
FTP разные кодировки названий

FTP разные кодировки названий

Использую apache ftp client, но проблема в том, что на FTP файлы с разными кодировкамиВот вывод консоли, если я ставлю UTF-8:

217
Изменить/Задать имя процессу Java

Изменить/Задать имя процессу Java

Если такое возможно без сторонних программ типа Launch4J

198