2010-12-05 24 views
5

He experimentado un poco con los mensajes de socket TCP asíncrono entre dos programas, para pasar datos, números y/o texto. Lo que he hecho es usar una palabra clave al comienzo de cada mensaje, y luego separar los valores con el "|" personaje. Por lo que un mensaje puede tener este aspecto:Cómo separar los mensajes de socket TCP

"DATOS | 490 | 40517,9328222222 | 1 | 6 | 11345 | 11347 | 11344 | 11345 | 106 | 40517,8494212963"

fijo el tamaño de búfer de lectura en 1024, ya que la mayoría de los mensajes estará dentro de esa longitud. Sin embargo, a veces puedo enviar rápidamente muchos mensajes cortos donde varios juntos tienen menos de 1024 caracteres, y parece que se leerá de una vez. Y si envío un mensaje de más de 1024 caracteres, se dividirá. Así que estoy buscando algunos consejos sobre cómo manejar esto. ¿Debo usar algunos caracteres especiales para iniciar y/o finalizar cada mensaje? Agradecería algunos consejos sobre cómo hacer esto ...

Respuesta

5

La forma más sencilla sería enviar la longitud del mensaje al comienzo de cada mensaje, serializado de manera que funcione en hardware little-endian y big-endian .

Esto podría ayudar a su receptor a preasignar su búfer de recepción de manera eficiente también.

+0

Gracias! ¿A qué te refieres con serializar? ¿Se aplica a las PC estándar operadas por Windows? Con su último comentario, ¿significa que debería cambiar el tamaño del búfer según el mensaje que se recibe? Cómo funcionará esto ... Dado que la longitud del mensaje no se conoce hasta que el mensaje ya se haya leído, no entiendo exactamente a qué se refiere. Por cierto; ¿Tiene sentido dividir un mensaje en el lado del remitente, o esto no tendrá ningún impacto en el rendimiento? El tamaño será un mensaje de 50 caracteres cada 200 ms, y raramente un mensaje de 50,000-400,000 caracteres. – bretddog

+0

Serializar solo significa "dar salida como una cadena". La sugerencia de @terminus sería una forma razonable de hacerlo: convierta la longitud del mensaje en una cadena de longitud fija para que se convierta fácilmente en una 'int sin firmar 'en el lado de recepción. Puede solicitar leer muchos bytes primero en un búfer de tamaño fijo, y luego asignar un búfer para recibir el resto del mensaje. No se moleste en dividir el mensaje en el lado de envío: la pila TCP/IP realizará cualquier paquetización requerida. –

+0

¡salud! Creo que lo entendí ahora :) – bretddog

3

La manera más fácil sería enviar el tamaño del mensaje al principio del paquete. De esta forma sabría la cantidad de datos para leer. Entonces se vería así:

00015MESSAGE|1|2 ... 

Es importante que el campo de tamaño tenga un tamaño fijo.

También puede hacer que este campo de tamaño sea binario, pero parece que está enviando texto sin formato para que así tenga un campo de tamaño humanamente legible.

0

Puede resolver ese problema rellenando sus mensajes con bytes únicos (como 255 que no aparecen en ASCII) para el tamaño del búfer y eliminarlos en el extremo receptor. Para mí, este no es un arreglo muy agradable e inteligente, pero en realidad funciona.

O podría tratar de enviar la longitud total del paquete al comienzo de cada paquete, que es un poco más desafiante y funciona de manera más eficiente como la técnica de relleno cuando se hace bien. paquetes resultante de la fusión a continuación tienen el siguiente aspecto (esquema):

05|.....02|..03|... 
0

La forma TAR lo hace, es el uso de bloques de tamaño fijo. Cada bloque en TAR tiene 512 bytes, y el archivo (mensaje) puede estar completamente contenido dentro de ese bloque. Si no es así, los primeros 512 bytes incluyen un encabezado que especifica cuántos bloques adicionales deben leerse para ese archivo (mensaje).

Tar no es una aplicación TCP obviamente, pero tiene requisitos de procesamiento o análisis de datos similares.

También Su tamaño es menor que 512 bytes, pero quizás tenga sentido incluir un bloque de 64 bytes, o 128 o lo que sea, y enviar todos sus datos en paquetes de ese tamaño. pierde eficiencia con la sobrecarga del "tamaño de la caja", pero puede ganar en eficiencia y simplicidad en el algoritmo de procesamiento de datos.

1

Hay varios enfoques.

  1. Una palabra de longitud prefijada a cada mensaje.

  2. Envoltura al estilo STX/ETX de cada mensaje para que pueda ver dónde comienza y termina. Esto requiere el escape de los bytes ETX que ocurren en los datos, y que a su vez también requiere el escape de los bytes ESC.

  3. Protocolo de autodescripción, por ejemplo XML, o un protocolo basado en el valor de longitud de tipo.

+0

El OP ya tiene que escapar de los caracteres '|' que aparecen en los datos, por lo que puede que no sea una carga. – caf

1

El protocolo es todo. Por mi aplicación de chat que utilizo el protocolo argumento como cuando se ejecuta

shutdown.exe -s -f -t 30 

Pero entonces para sockets utilizo este

join John%20Doe   ' %20 for space 
msg This%20Is%20a%20test ' again %20 for space 

De esta manera no importa si sus datos es enviar ASYNC: D Espero que esta ayuda

Cuestiones relacionadas