Cómo implementar un protocolo de red?


Aquí hay una pregunta genérica. No estoy en busca de la mejor respuesta, sólo me gustaría que expresaras tus prácticas favoritas.

Quiero implementar un protocolo de red en Java (pero esta es una pregunta bastante general, me enfrenté a los mismos problemas en C++), esta no es la primera vez, ya que lo he hecho antes. Pero creo que me falta una buena manera de implementarlo. De hecho, generalmente se trata de intercambiar mensajes de texto y algunos búferes de bytes entre hosts, almacenar el estado y esperar hasta el siguiente mensaje viene. El problema es que generalmente termino con un montón de instrucciones switch y más o menos complejas if que reaccionan a diferentes estados / mensajes. Por lo general, todo se complica y es difícil de mantener. Sin mencionar que a veces lo que sale tiene algún "punto ciego", me refiero a estados del protocolo que no han sido cubiertos y que se comportan de una manera impredecible. Traté de escribir algunas clases de máquinas de estado, que se encargan de comprobar los estados de inicio y fin para cada acción de manera más o menos inteligente. Esto hace que la programación del protocolo sea muy complicada ya que tengo que escribir líneas y líneas de código para cubrir todas las situaciones posibles. Lo que me gustaría es algo así como un buen patrón, o una mejor práctica que se utiliza en la programación de protocolos complejos, fácil de mantener y extender y muy legible.

¿cuáles son sus sugerencias?

Author: SilentGhost, 2010-03-15

8 answers

Lea el patrón de diseño State para aprender a evitar muchas sentencias switch.


"a veces lo que sale tiene algún "punto ciego", me refiero a estados del protocolo que no han sido cubiertos..."

State puede ayudar a evitar huecos. No puede garantizar un buen diseño, todavía tienes que hacer eso.

"as como tengo que escribir líneas y líneas de código para cubrir todas las situaciones posibles."

Esto no debe considerarse una carga o un problema: debe escribir líneas de código para cubrir cada situación posible.

State puede ayudar porque puede aprovechar la herencia. No puede garantizar un buen diseño, todavía tienes que hacer eso.

 16
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 21:54:53

El diseño de un protocolo generalmente se basa en el espacio de aplicación en el que está trabajando. Por ejemplo, http tiene que ver con el manejo de páginas web, gráficos y publicaciones, mientras que FTP tiene que ver con la transferencia de archivos.

Así que en resumen, para comenzar, debe decidir en qué espacio de aplicación se encuentra, luego definir las acciones que deben tomarse. Luego, finalmente, antes de comenzar a diseñar su protocolo real, debe buscar seriamente otra pila de protocolos que haga lo que desea para hacer y evitar la implementación de una pila de protocolos altoether. Solo después de haber determinado que algo más pre-construido absolutamente no funcionará para usted debe comenzar a construir su propia pila de protocolos.

 6
Author: Zak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 21:01:00

En C++ puedes usar la biblioteca Boost::Spirit para analizar tu mensaje de protocolo fácilmente. La única "dificultad" es definir la gramática de su protocolo de mensaje. Echa un vistazo al código fuente de Gnutella para ver cómo resuelven este problema. Aquí http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf son las especificaciones del protocolo Gnutella

 3
Author: miro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 21:52:02

Máquina de Estado finito es lo que quieres

FSM

Así que define un montón de estados en los que puede estar como receptor o remitente (idle, connecting_phase1, connecting_phase2, packet expected,...)

Luego defina todos los eventos posibles (packet1 arrives, net closes,...)

Finalmente tienes una tabla que dice 'cuando en el estado x y el evento n sucede hacer func y y transición al estado q' - para cada estado y evento (muchos serán null o dup)

Editar-cómo hacer un FSM (esbozo)

 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;

Estoy seguro de que esto está lleno de sintaxis inválida, pero espero que obtengas la deriva

 3
Author: pm100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 23:43:06

¿Por qué no usar XML como protocolo? Puede encapsular y categorizar todos sus datos dentro de nodos XML

 2
Author: Andres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 21:10:03

Yo mismo no puedo darte un ejemplo, pero ¿qué tal mirar cómo lo están haciendo otras personas (competentes)?

¿Te gusta este? http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/

P.d. Para el caso, realmente recomiendo usar netty como su marco de red y construir su protocolo encima de él. Debería ser muy fácil, y probablemente te desharás de muchos dolores de cabeza...

 2
Author: Enno Shioji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 21:17:46

Si está utilizando Java, considere mirar Apache MINA, su documentación y muestras deberían inspirarlo de la manera correcta.

 1
Author: incarnate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-15 20:56:37

Haga clic con el botón derecho en el icono de conexión de red de la Bandeja del sistema. Haga clic en Solucionar problemas. El solucionador de problemas puede encontrar y solucionar el problema, en este caso, puede comenzar rápidamente con su negocio. Si el solucionador de problemas no puede solucionar el problema de Winsocks, entonces puede obtener un error que se vea como: "Uno o más protocolos de red faltan en este equipo"

 0
Author: mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-03 06:43:18