Python Socket Flush

Estoy tratando de asegurarme de que cada vez que llamo a la función socket.send mi búfer se envíe (vacíe) a mi servidor (que está en C usando el socket Unix).

Desde mi entendimiento (y de lo que veo en este tablero) simplemente deshabilitando el naggle algo. Debería hacerlo, pero mi servidor aún recibe mis datos en una porción de 4096 bytes (conjunto predeterminado) …

Estoy usando el siguiente código en Python v2.5.4:

self.sck = socket( AF_INET, SOCK_STREAM ) self.sck.setsockopt( IPPROTO_TCP, TCP_NODELAY, 1 ) # That doesn't seems to work... self.sck.connect( ( "127.0.0.1", "12345" ) ) while( 1 ): self.sck.send( "test\n" ) self.sck.send( "" ) # Still trying to flush... 

Habilitar / deshabilitar TCP_NODELAY parece que no tiene ningún efecto en absoluto … ¿Es esto un error o me falta algo?

TIA

TCP no proporciona ningún tipo de envío de “paquetes” garantizados al otro extremo. Usted está enviando datos lo más rápido que puede, y TCP está ayudando a agrupar los datos en la medida en que puede enviarlos a la vez. Su servidor está recibiendo datos de 4096 bytes a la vez, probablemente porque eso es lo que pidió (en una llamada recv() ).

TCP es un protocolo de transmisión y, por lo tanto, tendrá que implementar algún tipo de enmarcado. No hay límites de mensajes integrados.

La única forma en que conseguí una descarga para trabajar (de regreso a un cliente C) fue mediante el uso de:

 my_writer_obj = mysock.makefile(mode='w', ...) my_writer_obj.write('my stuff') my_writer_obj.flush() 

La gran ventaja es que my_writer_obj utiliza de forma predeterminada el modo de texto, por lo que no hay más traducción de bytes.

crear un objeto lector no fue tan fácil, pero no necesitaba un color en ese lado.

No hay forma de asegurar el tamaño de los fragmentos de datos que se envían. Si desea asegurarse de que se envían todos los datos que desea enviar, puede cerrar la conexión:

 self.sck.close() 

Tenga en cuenta también que n = socket.send () devuelve el número de bytes enviados reales. Si definitivamente desea enviar todos los datos, debe utilizar

 self.sck.sendall() 

o bucle sobre el envío de datos:

 while data: n = self.sck.send(data) data = data[n:] 

(Pero eso es más o menos lo mismo que sendall ()). Si desea recibir los datos en fragmentos más grandes, puede boost el tamaño del búfer en recv (), pero esto solo hace que el tamaño del fragmento posible sea mayor. No hay garantía de que los datos lleguen en estos tamaños.

Esta es una pregunta común sobre el protocolo TCP. TCP en sí no tiene forma de enviar datos en fragmentos específicos. Está diseñado solo para enviar flujo de datos. Si necesita dicha funcionalidad, debe implementarla usted mismo. Por ejemplo, envíe sus trozos en líneas separadas o primero envíe el tamaño de trozo y luego el trozo en sí.

En la mayoría de los casos, no necesita preocuparse por el algoritmo de Naggle. Este algoritmo se describe mejor con el nombre TCP_NODELAY. Si lo desactiva, puede lograr retrasos más pequeños para trozos pequeños pero una velocidad más baja para trozos grandes al mismo tiempo.