Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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


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

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

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

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

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

Ответ 2

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

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

Ответ 3

Конечный автомат - это то, что вы хотите

FSM

Таким образом, вы определяете целую группу состояний, в которой вы можете находиться в качестве получателя или отправителя (idle, connection_phase1, connection_phase2, ожидаемый пакет,...)

Затем определите все возможные события (пакет1 прибывает, сеть закрывается,...)

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

Изменить - как сделать FSM (приблизительный эскиз)

 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;

Я уверен, что это полный недопустимый синтаксис, но я надеюсь, что вы получите дрифт

Ответ 4

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

Ответ 5

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

Ответ 6

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

Как этот? http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/

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

Ответ 7

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