Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Netty StartUp
#1
Всем привет. Изучаю механизм netty. И вот возник не большой вопрос. Надеюсь вы поможете мне. Итак поехали.

ЧТо я делаю? Создаю обычный сервер, который слушает строку. Если она есть то он выводит ее.

Реализация

Main

Pipeline
Handler

Значит рассказываю историю. Пишу к серверу клиентский сендер

Код:
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
        // TODO code application logic here
        Scanner console = new Scanner(System.in);
        Socket sock = new Socket("IP",3003);
PrintWriter writer = new PrintWriter(sock.getOutputStream());
while(true){
    System.out.println("Text: ");
    String s = console.nextLine();
    writer.println(s+"\0");
    writer.flush();
}

    }
}

Посылаю строки. Ок. Сервер принимает их и выводит на экран. Грубо говоря срабатывает переопределенный метод messageReceived.

Теперь дальше. Запускаю игру. Конекчусь на сервер в надежде получить ТО что отсылает игра серверу. Не важно поток байтов или что. Просто получить и прочитать так сказать.

Что происходит:
Сервер говорит что есть конект. Следовательно в хэндлере срабатывает channelConnected. Ок.. Казалось бы все хорошо, но сервер не пишет мне то что он получил от игры. Отсюда вывод. Не сработал метод messageReceived.
+ я перестраховался. Просто сделал вывод в консоль сообщения если метод сработал. - Не сработал.

Я немного подумал над тем почему и что так. Перечитав код несколько раз подозрительно оказалось в пайплайне

Код:
public class NettyServerPipeLineFactory implements ChannelPipelineFactory {
    @Override
public ChannelPipeline getPipeline() throws Exception {

ChannelPipeline pipeline = pipeline();

pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());

pipeline.addLast("handler", new NettyServerHandler());

return pipeline;
}
}

А именно
pipeline.addLast("decoder", new StringDecoder());

Еще точнее StringDecoder()

Что это вабще такое? - Это стандартный строковый декодер. И как я понимаю для пакетов существует отдельный декодер.

Возвращаемся к вопросу почему же сервер ничего не вывел? - Наверно потому что декодер ничего не смог получить из канала поэтому не сработал метод на сообщение... Может быть я не прав.... А вабще это попахивает еще тем, что если не добавить к своей строке \0(конец сообщения) тогда эффект будет тот же самый.

Как я понимаю - мне надо менять декодер. Уважаемые форумчане. Прошу вашей помощи. Если не затруднит то с демонстрацией кода. Большое спасибо.
Ответ
#2
https://github.com/Camelion/jts - глянь как тут сеть написана...
Ответ
#3
linliss Написал:https://github.com/Camelion/jts - глянь как тут сеть написана...
https://github.com/Camelion/jts/tree/mas...on/network
А она работает?
Ответ
#4
Как я понимаю, мне надо позаимствовать из проекта класс PacketDecoder и переписать у себя следущее

pipeline.addLast("decoder", new PacketDecoder());

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

Добавлено через 1 час 36 минут
Рассказываю о результате. Вгляделся в проект пользователя linliss и понял следущее:

- Нужно менять кодек! Вот как я переписал кусок того злополучного кода:

Код:
pipeline.addLast("decoder", new FrameDecoder() {

            @Override
            protected Object decode(ChannelHandlerContext chc, Channel chnl, ChannelBuffer cb) throws Exception {
               System.out.println("Try to decode");
               if (cb.readableBytes() < 2)
                 return null;

                cb.markReaderIndex();

        byte first = cb.readByte();
        byte second = cb.readByte();
               return first;
              
            }
        });
Теперь вместо StringDecoder я использую FrameDecoder. При попытке послать hello все работает хорошо. Срабатывает messageReceived и выводит содержмое. Итак.. послал hello, сервер отвечает следущее:

Цитата:NettyServer: Listen to users NettyServerHandler:
Client connected from /IP:59961 (-209645230)
Try to decode
Bytes 104
Try to decode
Bytes 108

Метод opcode вернул результат byte first = cb.readByte();

Вопрос таков. Что это означает.

И еще проблема такого плана. Пытаюсб игрой сделать конект - сервер молчит. ничего не выводит, хотя байтики я ему послал(игрой).
Ответ
#5
Попробуй так
Код:
@Override
            protected Object decode(ChannelHandlerContext chc, Channel chnl, ChannelBuffer cb) throws Exception {
               System.out.println("ChannelBuffer content: " + cb.toString(new Charset("UTF-8")));
            }

И убери из пипелайна

pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));
Ответ
#6
какой игрой?
Почему вы уверены, что игра что-то отправила?
Ответ
#7
@Java-man

Сделал так:
Код:
int first = cb.readByte();
        byte second = cb.readByte();
      
        System.out.println("ChannelBuffer content: " + cb.toString());
    
        
        
               return first+"-"+second;
Посылаю: 1234 Итог:

Цитата:Client connected from /IP:60390 (-202326428)
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=2, widx=6, cap=6)
Bytes49-50
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=4, widx=6, cap=6)
Bytes51-52
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=6, widx=6, cap=6)
Bytes13-10

При конекте игрой сервер ничего не выдает.


@KID
Первое что было под рукой это аион.

Почему я уверен в посыле байтов игрой? - Наверно потому что вместо сервера на этом же порте тестил конект на живом логин-сервере от этой игры. Логин писал типа посыл идет.

+ Я снифером смотрел. Снифер регистрирует передачу данных.

Добавлено через 8 минут
Дабы исключить такую мелоч, которую подкинул KID публикую скрин снифера и лог сервера

Цитата:NettyServerHandler:
Client connected from /10.3.20.240:61438 (-2135720860)

[Изображение: 9cUzP.jpg]

Добавлено через 1 час 37 минут
Если говорить точнее то когда я пытаюсь подключиться игрой то не срабатывает метод decode

Но что это дает.... пока не понятно.
Ответ
#8
Visor Написал:https://github.com/Camelion/jts/tree/mas...on/network
А она работает?

Она работает

grizly,
Цитата:Client connected from /IP:60390 (-202326428)
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=2, widx=6, cap=6)
Bytes49-50
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=4, widx=6, cap=6)
Bytes51-52
Try to decode
ChannelBuffer content: BigEndianHeapChannelBuffer(ridx=6, widx=6, cap=6)
Bytes13-10

отлично передал вашу строку. По таблице ASCII 49=1; 50=2; 51=3; 52=4; 13=CR; 10=LF;. Т.е. если вы передавали 1234 из консоли, у вас помимо цифр ещё передались символы возврата каретки и перевода строки
Ответ
#9
Camelion

Пришлось все это дело систематизировать. В итоге при передаче 1234 сервер выводит

Цитата:Try to decode
Byte = : 31
Try to decode
Byte = : 32
Try to decode
Byte = : 33
Try to decode
Byte = : 34
Try to decode
Byte = : D
Try to decode

Это очень сходится с фрагментом из снифера

[Изображение: zCQkS.jpg]

Таким образом я уже точно знаю, что имею дело с байтами. Но вопрос по прежнему меня тревожит ибо ответить на него смогут только гейм девелоперы. Почему же когда я пытаюсь сделать конект с игры(игры уже разные пробовал) то сервер ничего не выводит. Точнее почему не запускается метод decode? В чем проблема? Может я использую не тот кодек?

PS А что символизирует
Цитата:Try to decode
Byte = : 31
Try to decode
Byte = : 32
Try to decode
Byte = : 33
Try to decode
Byte = : 34
Try to decode
Byte = : D
Try to decode

Буква D ? И судя по всему после нее я могу еще вычитать А. О чем они говорят? (причем установлено, что при разных наборах D повторяется.)
Ответ
#10
grizly, может клиент ждет от вас первого пакета? Такое было, например, в lineage 2. При установлении соединения между клиентом и сервером, именно сервер посылал первый пакет. До тех пор, пока клиент не получит этот пакет, он не отправлял ничего в ответ(в вашем случае метод decode не вызывается). Попробуйте изучить протокол вашей игры, и узнать, какая сторона начинает "сетевое общение".

Во втором случае ничего не изменилось:
0D = 13 = CR
0A = 10 = LF
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Netty DieorL2 31 10,011 10-05-2012, 08:43 PM
Последний пост: shocked
  Netcore Source (Netty) n3k0nation 3 4,531 05-03-2010, 07:10 PM
Последний пост: Aquanox

Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)