socket sistemas programacion primitivas operativos los interfaz caracteristicas sockets network-protocols

sockets - sistemas - socket udp



Fundamentos del Protocolo de Socket (5)

Recientemente, mientras leía un HOWTO de programación de socket, la siguiente sección saltó sobre mí:

Pero si planea reutilizar su socket para futuras transferencias, debe tener en cuenta que no hay un "EOT" (Fin de la transferencia) en un socket. Repito: si un socket send o recv regresa después de manejar 0 bytes, la conexión se ha roto. Si la conexión no se ha roto, puede esperar a recibir una llamada para siempre, porque el conector no le dirá que no hay nada más que leer (por ahora). Ahora bien, si lo piensas un poco, te darás cuenta de una verdad fundamental de los sockets: los mensajes deben ser de longitud fija (yuck), o delimitados (shrug), o indicar cuánto tiempo están (mucho mejor), o finalizando la conexión . La elección es totalmente suya, (pero algunas formas son más adecuadas que otras).

Esta sección destaca 4 posibilidades de cómo un "protocolo" de socket puede escribirse para pasar mensajes. Mi pregunta es, ¿cuál es el método preferido para usar en aplicaciones reales?

¿Es generalmente mejor incluir el tamaño del mensaje con cada mensaje (presumiblemente en un encabezado), como afirma el artículo más o menos? ¿Hay alguna situación en la que otro método sea preferible?


Los protocolos comunes especifican la longitud en el encabezado o están delimitados (como HTTP, por ejemplo).

Tenga en cuenta que esto también depende de si usa sockets TCP o UDP. Como las tomas TCP son confiables, puedes estar seguro de que obtienes todo lo que introdujiste en ellas. Con UDP, la historia es diferente y más compleja.


No sé si hay una opción preferida. En nuestra situación del mundo real (aplicación cliente-servidor), usamos la opción de enviar la longitud total del mensaje como una de las primeras piezas de datos. Es simple y funciona tanto para nuestras implementaciones TCP como UDP. Hace la lógica razonablemente "simple" al leer datos en ambas situaciones. Con TCP, la cantidad de código es bastante pequeña (en comparación). La versión de UDP es un poco (insuficiente) más compleja, pero aún depende del tamaño que se pasa en el paquete inicial para saber cuándo se han enviado todos los datos.


Estas son de hecho nuestras elecciones con TCP. HTTP, por ejemplo, usa una combinación de segunda, tercera y cuarta opción (doble encabezado de solicitud / respuesta de final de línea nueva, que puede contener el encabezado Content-Length o indicar codificación fragmentada , o podría decir Connection: close y no dar tienes la duración del contenido, pero esperas que confíes en leer EOF.)

Prefiero la tercera opción, es decir, los mensajes de autodescripción, aunque la longitud fija es sencillamente fácil cuando corresponde.


Si está diseñando su propio protocolo, primero mire el trabajo de otras personas; puede que ya exista algo similar que podría usar ''tal cual'' o readaptar y ajustar. Por ejemplo; ISO-8583 para txns financieros, HTTP o POP3 hacen las cosas de forma diferente, pero de manera comprobada que funcionan ... De hecho, vale la pena mirar estas cosas de todos modos, ya que aprenderá mucho sobre cómo se combinan los protocolos del mundo real.

Si necesita escribir su propio protocolo, entonces, en mi humilde opinión, prefiero los mensajes prefijados de longitud siempre que sea posible. Son fáciles y eficientes de analizar para el receptor, pero posiblemente más difíciles de generar si es costoso determinar la longitud de los datos antes de comenzar a enviarlos.


La decisión debería depender de los datos que desea enviar (qué es, cómo se recopila). Si los datos son de longitud fija, entonces los paquetes de longitud fija probablemente sean los mejores. Si los datos pueden ser fácilmente (no se necesita escaparse) divididos en entidades delimitadas, entonces la delimitación puede ser buena. Si conoce el tamaño de los datos cuando comienza a enviar la pieza de datos, entonces el prefijo de len puede ser incluso mejor. Si los datos enviados son siempre caracteres individuales, o incluso bits individuales (por ejemplo, "activado" / "desactivado"), todo lo que sea diferente de los mensajes de caracteres de tamaño fijo será demasiado.

También piense cómo puede evolucionar el protocolo. Las cadenas delimitadas por EOL son buenas siempre que no contengan caracteres EOL. La longitud fija puede ser buena hasta que los datos se puedan extender con algunas partes opcionales, etc.