2009-10-31 12 views
9

He escrito un servidor en Python que debe enviar datos al cliente en el formulario "Encabezado: Mensaje"¿Cómo se limpian los zócalos de Python?

Me gustaría poder enviar cada mensaje individualmente para que el cliente necesite realizar un trabajo mínimo para leer el "encabezado" y el "mensaje"

Desafortunadamente, no puedo encontrar la forma de purgar correctamente un socket de python, así que cuando tengo varios envíos ejecutan en sucesión rápida los mensajes se agrupan en el buffer de socket y enviado como un gran pedazo.

Ejemplo:

Server envía ...

socket.send ("header1:message1") 
socket.send ("header2:message2") 
socket.send ("header3:message3") 

cliente recibe ... "header1: message1header2: message2header3: Message3"

Me gustaría recibir tres mensajes individuales

header1:message1 
header2:message2 
header3:message3 

Necesito una forma de enjuagar después de eac h envíe

+0

duplicado exacto: http://stackoverflow.com/questions/1097974/how-to-flush-a-socket-in-python – ChristopheD

+4

* No es un duplicado : * El título es * literalmente * un duplicado, pero la pregunta es de hecho * funcionalmente * diferente. El OP necesita una respuesta como @ebo a continuación. –

+1

Vaya, eso parece ser correcto. Trataré de ser un poco más lento la próxima vez ;-) – ChristopheD

Respuesta

19

Supongo que está hablando a través de una conexión TCP.

Su enfoque es defectuoso. Una secuencia TCP se define como una secuencia de bytes. Siempre debe usar algún tipo de separador y no puede depender de la pila de la red para separar sus mensajes.

Si realmente necesita servicios basados ​​en datagramas, cambie a UDP. Tendrá que gestionar la retransmisión usted mismo en ese caso.

Para aclarar:

Lavado del buffer de envío por lo general crea nuevos paquetes, tal como se esperaba. Si su cliente lee estos paquetes lo suficientemente rápido, puede recibir un mensaje por lectura.

Ahora imagine que se comunica a través de un enlace de satélite. Debido al alto ancho de banda y la latencia, el último enrutador antes del satélite espera un corto tiempo hasta que haya suficientes datos en el búfer y envía todos sus paquetes a la vez. Su cliente ahora recibirá todos los paquetes sin demora y colocará todos los datos en el búfer de recepción a la vez. Entonces tu separación se ha ido otra vez.

+0

+1: Yo añadiría por el bien de edumacations que, incluso si @Jah fuera a enjuagar los sockets, su cliente aún recibiría los mensajes exactamente de la misma manera - el enrojecimiento es sobre la eliminación de almacenamientos intermedios en nombre de la reducción de latencia y * no * demarcación de mensajes. –

+0

Dio un escenario para mostrar cómo puede salir mal. thx @ stu – ebo

+0

+1: TCP es una transmisión. La temporización de los datos TCP se elimina específicamente mediante el enrutamiento de Internet y el protocolo TCP. Los datos deben ser almacenados en búfer; "enrojecer" en realidad no significa mucho. Todo lo que significa es que sus datos están fuera de los búferes de su aplicación y en el búfer del protocolo TCP. –

0

Lo que estás tratando de hacer es dividir tus datos en "lotes".

Por ejemplo, está operando en "lotes" cada vez que lee "líneas" de un archivo. ¿Qué define una "línea"? Es una secuencia de bytes terminada por '\ n'. Otro ejemplo es: usted lee 64KiB "trozos" de un archivo. ¿Qué define un "pedazo"? Lo haces, ya que lees 65536 bytes cada vez. ¿Quieres un "trozo" de longitud variable? Simplemente prefija su "pedazo" con su tamaño, luego lea el "trozo". Los archivos "aiff" (cuyas implementaciones son también los archivos .wav y .avi de MS Windows) y los archivos "mov" están organizados de esa manera.

Estos tres métodos son los métodos más fundamentales para organizar un flujo de bytes, cualquiera que sea el medio:

  1. discos separadores
  2. registros de tamaño fijo
  3. registros prefijados con su tamaño.

Se pueden mezclar y/o modificar. Por ejemplo, podría tener "separadores de registros variables", como un lector XML: lea bytes del primero '<' hasta el primer '>', agregue una barra después del primero '<' y llámelo final de registro, lea la secuencia hasta fin de registro Esa es solo una descripción cruda.

Elija un método e impleméntelo tanto en el escritor como en el lector. Si también documenta sus elecciones, acaba de definir su primer protocolo.

3

acaba de añadir \ n después de cada mensaje ... como

socket.send ("header1: mensaje 1 \ n")

socket.send ("header2: mensaje2 \ n")

socket.send ("header3: Message3 \ n")

+1

¡Esto funcionó para mí! –

+0

"\ n" no garantiza que los mensajes estén separados. – crey4fun

Cuestiones relacionadas