2009-05-27 18 views
19

No sé mucho acerca de los sockets, excepto cómo leerlos y escribirles como si fueran archivos. Sé un poco sobre el uso de selectores de socket. No entiendo por qué tienes que enjuagar un socket, ¿qué está pasando realmente allí? ¿Los bits se cuelgan en algún lugar de la memoria hasta que se los quitan? Leí algunas cosas en línea sobre sockets, pero todo es muy abstracto y de alto nivel.¿Qué significa enjuagar un enchufe?

¿Qué está pasando realmente aquí?

Respuesta

42

Hay una cierta cantidad de gastos generales involucrados al escribir en un socket de red y enviar datos. Si se envían datos cada vez que se ingresa byte en el socket, terminaría con más de 40 bytes de encabezado TCP por cada byte de datos reales. (Suponiendo que está usando un socket TCP, por supuesto. Otros sockets tendrán diferentes valores). Para evitar tal ineficiencia, el socket mantiene un búfer local, que suele ser algo más de 1000 bytes. Cuando se completa ese búfer, se envuelve un encabezado alrededor de los datos y el paquete se envía a su destino.

En muchos casos, no necesita que cada paquete se envíe inmediatamente; Si está transfiriendo un archivo, es posible que los datos iniciales no sirvan sin los datos finales del archivo, por lo que esto funciona bien. Sin embargo, si necesita forzar que los datos se envíen inmediatamente, al enjuagar el búfer se enviarán los datos que aún no se hayan enviado.

Tenga en cuenta que cuando cierra un socket, se vacía automáticamente cualquier información remanente, por lo que no es necesario enjuagar antes de cerrar.

+0

¿Cómo se relaciona NAGL con esto, sabes? – rogerdpack

+0

gran respuesta .... – goh

1

No he usado el enjuague para la programación del socket. Recuerdo en algún lugar que hay modos que puede establecer, donde los envíos orientados a la transmisión intentan reducir la cantidad de paquetes pequeños enviados. Sin embargo, usaría un sendall() para asegurarse de que se envíe todo en el búfer.

La función shutdown() es muy útil cuando se está enrollando. Por supuesto que debe usar una llamada a close() si no quiere cosas por ahí.

Echa un vistazo a Beej's guide para obtener más información.

+3

sendall() es lo mismo que flush() –

2

El algoritmo de Nagle a menudo se usa en los sockets. En pocas palabras, espera hasta que haya una cantidad no trivial de datos para enviar. El problema es lograr un equilibrio entre la latencia de transmisión y el costo general de enviar un paquete de datos.

Cuanto mayor es la carga útil de los datos, menor es el ancho de banda desperdiciado porque el encabezado es (principalmente) de tamaño fijo. Además, los sistemas intermedios generalmente tienen límites de rendimiento basados ​​más significativamente en la velocidad de paquete, no en la velocidad de datos general.

+0

Sin embargo, esta respuesta en realidad no aborda cómo enjuagar un socket. –

9

No se puede lavar realmente una toma de corriente.

(De How can I force a socket to send the data in its buffer?)

No se puede forzar. Período. TCP toma una decisión sobre cuándo puede enviar datos. Ahora, normalmente cuando se llama a write() en un socket TCP,
TCP enviará efectivamente un segmento, pero no hay garantía ni forma de forzar esto. Hay muchas razones por las cuales TCP no enviará un segmento
: una ventana cerrada y el algoritmo de Nagle son dos cosas para
que vienen inmediatamente a la mente.

Lea la publicación completa, es bastante profunda y aclara muchas de las cosas para mí.