2009-06-25 10 views
9

Estoy a punto de escribir un protocolo de mensaje sobre una transmisión TCP. El receptor necesita saber dónde están los límites del mensaje.Escribir un protocolo de flujo: ¿Campo de tamaño de mensaje o delimitador de mensaje?

Puedo enviar 1) mensajes de longitud fija, 2) campos de tamaño para que el receptor sepa qué tan grande es el mensaje, o 3) un terminador de mensaje único (supongo que no se puede usar en ningún otro lugar del mensaje) .

No utilizaré el n. ° 1 por razones de eficiencia.

Me gusta el n. ° 2 pero, ¿es posible que la transmisión se desincronice?

No me gusta la idea n. ° 3 porque significa que el receptor no puede conocer el tamaño del mensaje con anticipación y también requiere que el terminador no aparezca en ningún otro lugar del mensaje.

Con el n. ° 2, si es posible desconectarme, ¿puedo agregar un terminador o me garantizo que nunca se desincronizará siempre que el programa del remitente sea correcto en lo que envía? ¿Es necesario hacer # 2 Y # 3?

Háganme saber.

Gracias, JBU

Respuesta

5

está usando el TCP, la entrega de paquetes es fiable. Entonces, la conexión se desactiva, se agota el tiempo de espera o leerás todo el mensaje. Así que la opción # 2 está bien.

3

Dependiendo del nivel en el que esté trabajando, el # 2 puede no tener problemas para desconectarse (TCP tiene una numeración de secuencia en los paquetes, y vuelve a ensamblar la secuencia en el orden correcto para usted si llega fuera de servicio).

Por lo tanto, # 2 es probablemente su mejor opción. Además, conocer el tamaño del mensaje al principio de la transmisión facilitará la asignación de memoria en el extremo receptor.

+0

_Además, conocer el tamaño del mensaje al principio de la transmisión facilitará la asignación de memoria en el extremo receptor._ Una palabra de cuidado: asegúrese de limitar la cantidad de memoria asignada. De lo contrario, usted es susceptible a ataques DDoS con paquetes personalizados que tienen un campo de tamaño de 2^32-1 (o por más grandes que sean sus enteros), llenando rápidamente su memoria. – Kenji

1

Si está desarrollando tanto el código de transmisión como el de recepción desde cero, no estaría de más utilizar tanto los encabezados de longitud como los delimitadores. Esto proporcionaría robustez y detección de errores. Considere el caso donde solo usa # 2. Si escribe un campo de longitud de N en la secuencia TCP, pero termina enviando un mensaje que es de un tamaño diferente de N, el receptor no sabría nada mejor y terminaría confundido.

Si utiliza ambos # 2 y # 3, aunque no es infalible, el receptor puede tener un mayor grado de confianza de que recibió el mensaje correctamente si encuentra el delimitador después de consumir N bytes de la secuencia TCP. También puede usar el delimitador de forma segura dentro de su mensaje.

Eche un vistazo a HTTP Chunked Transfer Coding para obtener un ejemplo real del uso de # 2 y # 3.

2

Estoy de acuerdo con sigjuice. Si tiene un campo de tamaño, no es necesario para agregar y delimitador de final de mensaje - sin embargo, es una buena idea. Tener ambos hace las cosas mucho más robustas y más fáciles de depurar.

Considere utilizar el estándar netstring format, que incluye un campo de tamaño y también un carácter de fin de cadena. Como tiene un campo de tamaño, está bien que el carácter de fin de cadena se use dentro del mensaje.

0

Existe una cuarta alternativa: un protocolo de autodescripción como XML.

+0

Esto no es adecuado para mensajes binarios puros. Básicamente es la opción n. ° 3 pero mucho peor que un delimitador único. – Lucretiel

2

Interesante no hay una respuesta clara aquí. # 2 es seguro sobre TCP sin importar qué, y se hace "en el mundo real" con bastante frecuencia. Esto se debe a que TCP garantiza que todos los datos lleguen tanto sin daños como en el orden en que se enviaron, por lo que no existe la posibilidad de que una implementación correcta se desincronice.

Cuestiones relacionadas