Как реализовать сетевой протокол?

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

Я хочу реализовать сетевой протокол в Java (но это - довольно общий вопрос, я столкнулся с теми же проблемами в C++), это не первый раз, поскольку я сделал это прежде. Но я думаю, что пропускаю хороший способ реализовать его. На самом деле обычно это - все об обмене текстовыми сообщениями и некоторыми буферами байта между хостами, храня состояние, и ожидайте, пока следующее сообщение не появляется. Проблема состоит в том, что я обычно заканчиваю с набором переключателя и более или менее сложный, если операторы, которые реагируют на различные состояния / сообщения. Все это обычно сложно и трудно поддержать. Не говоря уже о том, что иногда то, что выходит, имеет некоторую "мертвую зону", я имею в виду состояния протокола, которые не были охвачены и которые ведут себя непредсказуемым способом. Я пытался записать некоторые классы конечного автомата, которые заботятся о проверке, запускают и заканчивают состояния для каждого действия более или менее умными способами. Это делает программирование протокола очень сложным, поскольку я должен записать строки и строки кода для покрытия каждой возможной ситуации. То, что я хотел бы, является чем-то как хороший шаблон или лучшая практика, которая используется в программировании сложных протоколов, легких поддержать и расшириться и очень читаемый.

Каковы Ваши предложения?

34
задан SilentGhost 12 May 2010 в 12:19
поделиться

7 ответов

Прочтите шаблон проектирования State , чтобы узнать, как избежать большого количества операторов switch.


«иногда то, что выходит, имеет некоторую« слепую зону », я имею в виду статусы протокола, которые не были охвачены ...»

Состояние может помочь избежать пробелов. Это не может гарантировать хорошего дизайна, вам все равно придется это делать.

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

Это не следует рассматривать как бремя или проблему: вы должны написать строки кода чтобы охватить все возможные ситуации.

Состояние может помочь, потому что вы получаете возможность использовать наследование. Это не может гарантировать хорошего дизайна, вам все равно придется это делать.

16
ответ дан 27 November 2019 в 17:12
поделиться

Почему бы не использовать XML в качестве протокола? Вы можете инкапсулировать и классифицировать все ваши части данных внутри узлов XML

2
ответ дан 27 November 2019 в 17:12
поделиться

Разработка протокола обычно зависит от области применения, в которой вы работаете. Например, протокол http предназначен для работы с веб-страницами, графикой и сообщениями, а FTP - для передачи файлов.

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

6
ответ дан 27 November 2019 в 17:12
поделиться

Finite State Machine - это то, что вам нужно

FSM

Итак, вы определяете целую кучу состояний, в которых вы можете находиться как получатель или отправитель (idle, connecting_phase1, connecting_phase2, packet expected,...)

Затем определяете все возможные события (packet1 arrives, net closes, ...)

Наконец, вы получаете все возможные события (packet1 arrives, net closes, ...). )

Наконец, у вас есть таблица, которая говорит: "когда в состоянии x происходит событие n, выполните функцию y и перейдите в состояние q" - для каждого состояния и события (многие будут null или dups)

Edit - how to make a FSM (rough sketch)

 struct FSMNode
 {
      int m_nextState;
      void (m_func*);
 }
 FSMNode states[NUMSTATES][NUMEVENTS]=
   { // state 0
      {3, bang}, // event 0
      {2,wiz},
      {1, fertang}
    }
    {
      {1, noop}, // event 0
      {1, noop},
      {3, ole}
     }
     .......
     FSMNode node = states[mystate][event];
     node.m_func(context);
     mystate = node.m_nextState;

Я уверен, что здесь много неправильного синтаксиса - но надеюсь, вы уловили суть

.
3
ответ дан 27 November 2019 в 17:12
поделиться

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

1
ответ дан 27 November 2019 в 17:12
поделиться

Не могу привести пример сам, но как насчет того, чтобы посмотреть, как это делают другие (компетентные) люди?

Например, вот это? http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/

P.S. Если уж на то пошло, я рекомендую использовать netty в качестве сетевого фреймворка и строить свой протокол поверх него. Это должно быть очень просто, и вы, вероятно, избавитесь от кучи головной боли...

2
ответ дан 27 November 2019 в 17:12
поделиться

В C ++ вы можете использовать библиотеку Boost :: Spirit для анализа вашего протокол сообщения легко. Единственная «трудность» - это определить грамматику вашего протокола сообщений. Взгляните на исходный код Gnutella, чтобы увидеть, как они решают эту проблему. Здесь http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf - это спецификации протокола Gnutella

3
ответ дан 27 November 2019 в 17:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: