Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> netty. TCP Пакет приходит не полностью. 
V
    Опции темы
Felixx
Дата 16.12.2013, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 4.12.2008

Репутация: нет
Всего: нет



Подскажите пожалуйста, из-за чего может быть следующая ситуация?
В основном один из TCP пакетов приходит сразу и полностью, в его Data к примеру 90 байт.
Но бывают моменты, совершенно не понятно почему и  без всякой видимой логики:
Приходит этот же пакет, но не 90 а например 70 байт, так как описание пакета уже расчитана на прием 90 байт возникают исключения что нехватает байтов.
Если сделать break записать что есть в Temp буффер, поймать следующий пакет, то придет оставшийся "Хвост" в 20 байт... добавим его в Temp и все как бы хорошо и отлично. Но иногда "хвост" может отрезаться не в 20 а в 30 байт, тоесть совсем беспорядочно. Дело не в клиенте, так как проверялось на C#, и на другом Java движке.... там "Хвосты не отрубались" и разу.
Мне подсказали что надо поставить флаг TCP_NODELAY ... поставил и не помогло.

Привожу код...
Сам старт сервера.
Код

package ru.pb.game.network.client;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.pb.game.properties.GameServerProperty;

import java.net.InetAddress;
import java.net.InetSocketAddress;

import static io.netty.channel.ChannelOption.*;

public class ClientServer implements Runnable {

    private static final Logger log = LoggerFactory.getLogger(ClientServer.class);
    private static final ServerBootstrap server = new ServerBootstrap();

    private static final String host = GameServerProperty.getInstance().GAME_SERVER_HOST;
    private static final int port = GameServerProperty.getInstance().GAME_SERVER_PORT;
    private static final int boss = GameServerProperty.getInstance().GAME_SERVER_COUNT_BOSS_THREADS;
    private static final int work = GameServerProperty.getInstance().GAME_SERVER_COUNT_WORK_THREADS;

    public ClientServer() {
        server.option(TCP_NODELAY, false);
        server.childOption(TCP_NODELAY, false);

        server.group(new NioEventLoopGroup(boss), new NioEventLoopGroup(work));
        server.channel(NioServerSocketChannel.class);
        server.childHandler(new ClientChannelInitializer());
    }

    public static void shutdown() {
        server.group().shutdownGracefully();
        log.info("The server has been shutdown!");
    }

    @Override
    public void run() {
        try {
            InetSocketAddress ad = host.equals("*") ? new InetSocketAddress(port) : new InetSocketAddress(InetAddress.getByName(host), port);
            log.info("Listening to the client connections in [" + ad + "]");
            server.bind(ad).sync().channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            shutdown();
        }
        log.info("Networking is closed!");
    }
}


Инициализатор канала.
Код

public class ClientChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    public void initChannel(SocketChannel channel) throws Exception {
        channel.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG), new ClientConnection());
    }
}


Обработка принятого пакета из класса ClientConnection -> extends Connection -> extends ChannelInboundHandlerAdapter
Код

private ByteBuf temp;
    private boolean error = false;

@Override
    public boolean readPacket(ByteBuf buffer) {
        if (error) {
            log.info("=============== BAD PACKET =================");
            log.info(NetworkUtil.printData("============ REC PACKET", buffer));
            temp.writeBytes(buffer, 0, buffer.readableBytes());
            error = false;
            buffer.clear();
            buffer.writeBytes(temp, 0, temp.readableBytes());
            //log.info(NetworkUtil.printData("============ BAD PACKET", buffer));
            temp.clear();
            ReferenceCountUtil.release(temp);
        }

        int count = 0;
        while (buffer.readableBytes() > 0) {
            count++;
            if (count > 1) {
                log.info("PACKET COUNT : " + count);
            }
            int size = buffer.readUnsignedShort();
            int decoded = (size & 0x7FFF) + 2;
            if (decoded > buffer.readableBytes()) {
                temp = Unpooled.buffer().order(ByteOrder.LITTLE_ENDIAN);
                temp.writeBytes(buffer, 0, buffer.readableBytes() + 2);
                error = true;
                break;
            }
            read(size > 0x22CC ? decode(buffer.readBytes(decoded)) : buffer.readBytes(decoded));
        }
        return true;
    }

private void read(ByteBuf buffer) {
        ClientPacket packet = GamePacketHandler.getInstance().handle(buffer, this);
        showPackageHex(buffer);
        if ((packet != null) && packet.read()) {
            log.info(this + " reading packet: " + packet);
            packet.setBuf(null);
            processor.executePacket(packet);
        }
    }


Результаты работы...
Код

[12:14:25|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]=============== BAD PACKET =================
[12:14:25|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]============ REC PACKET [9B]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 04 00 00 00 00 00                      |.........       |
+--------+-------------------------------------------------+----------------+
[12:14:25|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] reading packet: [C] 0xC11 CM_ROOM_CREATE
[12:14:25|INFO |PacketProcessor:0     |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] sending packet: [S] 0xC12 SM_ROOM_CREATE


[12:16:55|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]=============== BAD PACKET =================
[12:16:55|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]============ REC PACKET [25B]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 00 00 00 00 00 00 00 00 00 01 08 00 00 |................|
|00000010| 00 00 00 04 00 00 00 00 00                      |.........       |
+--------+-------------------------------------------------+----------------+
[12:16:55|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] reading packet: [C] 0xC11 CM_ROOM_CREATE
[12:16:55|INFO |PacketProcessor:0     |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] sending packet: [S] 0xC12 SM_ROOM_CREATE

[12:18:00|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]=============== BAD PACKET =================
[12:18:00|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]============ REC PACKET [25B]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 00 00 00 00 00 00 00 00 00 01 08 00 00 |................|
|00000010| 00 00 00 04 00 00 00 00 00                      |.........       |
+--------+-------------------------------------------------+----------------+
[12:18:00|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] reading packet: [C] 0xC11 CM_ROOM_CREATE
[12:18:00|INFO |PacketProcessor:0     |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] sending packet: [S] 0xC12 SM_ROOM_CREATE

[12:18:22|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]=============== BAD PACKET =================
[12:18:22|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]============ REC PACKET [11B]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 08 00 00 00 00 00 20 04                |......... .     |
+--------+-------------------------------------------------+----------------+
[12:18:22|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] reading packet: [C] 0xC11 CM_ROOM_CREATE
[12:18:22|INFO |PacketProcessor:0     |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] sending packet: [S] 0xC12 SM_ROOM_CREATE

[12:19:33|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]=============== BAD PACKET =================
[12:19:33|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]============ REC PACKET [27B]
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 00 00 00 00 00 00 00 00 00 01 08 00 00 |................|
|00000010| 00 00 00 08 00 00 00 00 00 20 04                |......... .     |
+--------+-------------------------------------------------+----------------+
[12:19:33|INFO |nioEventLoopGroup-3-1 |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] reading packet: [C] 0xC11 CM_ROOM_CREATE
[12:19:33|INFO |PacketProcessor:0     |ClientConnection                   ]Client [id:1, ip: 192.168.1.43] sending packet: [S] 0xC12 SM_ROOM_CREATE




Прошу помощи или советов у знатаков netty... Заранее огромное спасибо!
PM MAIL   Вверх
Felixx
  Дата 17.12.2013, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 4.12.2008

Репутация: нет
Всего: нет



Кому интересно, все дело в том что метод readChannel не обеспечивает того, что пакет получен полностью.
у меня этот метод выглядит так:
Код

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        try {
            if (in.isReadable()) {
                readPacket(in.order(ByteOrder.LITTLE_ENDIAN));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            ReferenceCountUtil.release(msg);
        }
    }

По этому нужно либо в ручную записывать байты по порядку в список и вытаскивать оттуда свой нужный пакет.
Либо заюзать уже готовые решения от io.netty.. Например унаследовать свой класс Connection от ByteToMessageDecoder  или  LengthFieldBasedFrameDecoder....

Если у кого то есть примерчик использования этих декодеров, я был бы очень признателен, если сможете поделиться реализацией.

З.Ы
Огромное спасибо за наводку alexandy.

Это сообщение отредактировал(а) Felixx - 17.12.2013, 10:29
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.1240 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.