Как реализовать сетевой протокол? - PullRequest
33 голосов
/ 15 марта 2010

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

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

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

Ответы [ 8 ]

16 голосов
/ 15 марта 2010

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


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

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

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

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

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

6 голосов
/ 16 марта 2010

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

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

3 голосов
/ 16 марта 2010

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

3 голосов
/ 16 марта 2010

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

FSM

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

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

наконец, у вас есть таблица, в которой говорится: «когда в состоянии x и происходит событие n, делайте функцию и переходите в состояние 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;

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

2 голосов
/ 16 марта 2010

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

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

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

2 голосов
/ 16 марта 2010

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

1 голос
/ 15 марта 2010

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

0 голосов
/ 03 сентября 2018

Щелкните правой кнопкой мыши значок сетевого подключения на панели задач. Нажмите Устранить проблемы. Устранитель неполадок может найти и устранить проблему, в этом случае вы можете быстро приступить к работе. Если средство устранения неполадок не может решить проблему Winsocks, вы можете получить сообщение об ошибке, похожее на: «На этом компьютере отсутствуют один или несколько сетевых протоколов»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...