Estás trabajando sin conexión, espera a que vuelva la conexión a Internet

Problemas de diseño: envío de segmentos de datos pequeños sobre TCP con Winsock

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

Haga clic aquí para ver el artículo original (en inglés): 214397
Resumen
Cuando necesite enviar paquetes de datos pequeños sobre TCP, es especialmente importante el diseño de la aplicación de Winsock. Un diseño que no tiene en cuenta la interacción de confirmación retardada, el algoritmo de Nagle y el almacenamiento en búfer de Winsock puede afectar drásticamente al rendimiento. Este artículo trata de estos problemas, con un par de estudios de casos y deriva de una serie de recomendaciones para el envío de paquetes de datos pequeño eficientemente desde una aplicación de Winsock.
Más información

Fondo

Cuando una pila Microsoft TCP recibe un paquete de datos, un temporizador de retardo de 200 ms va. Cuando finalmente se envía un ACK, el temporizador se restablece e iniciará otro retraso de 200 ms al recibe el próximo paquete de datos.Para aumentar la eficacia de Internet y las aplicaciones de intranet, la pila TCP de Microsoft utiliza los siguientes criterios para decidir cuándo debe enviar una confirmación de los paquetes de datos recibidos:
  • Si se recibe el segundo paquete de datos antes de que caduque el temporizador de retardo, la confirmación es enviada.
  • Si hay datos para ser enviados en la misma dirección que la confirmación antes de que se recibió el paquete de datos segundo y caduca el temporizador de retardo, la confirmación se superpone con el segmento de datos y envía inmediatamente.
  • Cuando el temporizador caduca, la confirmación es enviada.
Para evitar que los paquetes de datos pequeño congestionar la red, la pila Microsoft TCP permite el algoritmo de Nagle predeterminada, lo que combina un búfer de datos pequeño de varias llamadas de envío y retrasos enviar hasta que se envía un ACK para el paquete de datos anterior se recibe desde el host remoto. Las siguientes son dos excepciones para el algoritmo de Nagle:
  • Si la pila unieron en un búfer de datos mayor que la unidad de transmisión máxima (MTU), un paquete de tamaño completo se envía inmediatamente sin esperar la confirmación desde el host remoto. En una red Ethernet, el valor de MTU de TCP/IP es 1460 bytes.
  • Para deshabilitar el algoritmo de Nagle para que se entreguen los paquetes de datos pequeño al host remoto sin demora, se aplica la opción de socket TCP_NODELAY.
Para optimizar el rendimiento en el nivel de aplicación, Winsock copias los búferes de datos de aplicación envían llamadas a un búfer de núcleo de Winsock. A continuación, en la pila se utiliza sus propias técnicas heurísticas (por ejemplo, el algoritmo de Nagle) para determinar cuándo permiten poner el paquete en el cable. Puede cambiar la cantidad de Winsock kernel búfer asignado al socket con la opción FTP (es 8 KB de forma predeterminada). Si es necesario, Winsock puede almacenar en búfer significativamente más que el tamaño del búfer del FTP. En la mayoría de los casos, la finalización del envío de la aplicación sólo indica el búfer de datos en una aplicación enviar llamada se copia en el búfer de núcleo de Winsock y no indica que los datos ha alcanzado el medio de red. La única excepción es cuando se deshabilita el búfer de Winsock estableciendo FTP en 0.

Winsock utiliza las siguientes reglas para indicar a la aplicación una finalización del envío (dependiendo de cómo se invoca el envío, la notificación de finalización puede ser la función de devolución de una llamada de bloqueo, señalización de un evento o llamar a una función de notificación etc.):
  • Si el socket es aún dentro de la cuota de FTP, Winsock copia los datos de la aplicación de envío e indica la finalización del envío a la aplicación.
  • Si el socket es más allá de la cuota de FTP y hay sólo un envío previamente almacenados en búfer todavía búfer de la pila del núcleo, Winsock copia los datos de la aplicación de envío e indica la finalización del envío a la aplicación.
  • Si el socket es más allá de la cuota de FTP y hay más de un búfer previamente envían búfer de la pila del núcleo, Winsock copia los datos de la aplicación de envío. Winsock no indica la finalización del envío a la aplicación hasta que la pila completa suficiente envía a colocar el zócalo dentro de cuota de FTP o sólo una condición de envío pendiente.

Caso práctico 1

Información general:

Un cliente Winsock TCP necesita enviar 10000 registros a un servidor TCP Winsock para almacenar en una base de datos. El tamaño de los registros varía de 20 bytes de longitud de 100 bytes. Para simplificar la lógica de la aplicación, el diseño es el siguiente:
  • El cliente realiza sólo envío bloqueo. El servidor realiza sólo recv bloqueo.
  • El socket de cliente el FTP establece en 0 para que cada registro sale en un segmento de datos único.
  • La recepción de llamadas de servidor en un bucle. El búfer que se registra en recepción es de 200 bytes para que cada registro puede recibirse en una recibir llamada.

Rendimiento:

Durante las pruebas, el desarrollador busca que el cliente puede enviar sólo cinco registros por segundo al servidor. Los 10000 registros totales, máximos en 976K bytes de datos (10000 * 100 / 1024), lleva más de media hora para enviar al servidor.

Análisis:

Dado que el cliente no establece la opción TCP_NODELAY, el algoritmo de Nagle obliga a la pila TCP que esperar una confirmación antes de pueda enviar otro paquete en el cable. Sin embargo, el cliente ha deshabilitado el búfer de Winsock estableciendo la opción FTP en 0. Por lo tanto, los 10000 enviar llamadas tienen que enviarse y ACK'ed por separado. Cada ACK es 200-ms retrasadas porque ocurre lo siguiente en la pila TCP del servidor:
  • Cuando el servidor recibe un paquete, el temporizador de retardo de 200 ms va.
  • El servidor no necesite enviar nada, por lo que no se superpone la confirmación.
  • El cliente no enviará otro paquete, a menos que el paquete anterior se confirma.
  • Caduca el temporizador de retardo en el servidor y la confirmación es enviada de vuelta.

Cómo mejorar:

Hay dos problemas con este diseño. En primer lugar, está el problema del temporizador de retardo. El cliente debe ser capaz de enviar dos paquetes en el servidor dentro de 200 ms. porque el cliente utiliza el algoritmo de Nagle predeterminada, debe usar el Winsock de búfer predeterminado y no establece SO_SNDBUF en 0. Una vez que la pila TCP ha unido un búfer más grande que la unidad de transmisión máxima (MTU), un paquete de tamaño completo se envía inmediatamente sin esperar la confirmación desde el host remoto.

En segundo lugar, este diseño requiere un envío para cada registro de tal tamaño pequeño. Envía esta pequeña de tamaño no es muy eficaz. En este caso, el programador desee cada registro a 100 bytes de relleno y enviar 80 registros a la vez desde un cliente de llamada. Para permitir que el servidor sabe cuántos registros se enviarán en total, el cliente que desee comenzar la comunicación con un encabezado de corrección de tamaño que contiene el número de registros que siga.

Caso práctico 2

Información general:

Una aplicación de cliente Winsock TCP abre dos conexiones con una aplicación de servidor de Winsock TCP proporciona servicio de cotizaciones de bolsa. La primera conexión se utiliza como un canal de comando para enviar el símbolo de cotización en el servidor. La segunda conexión se utiliza como un canal de datos para recibir la cotización en bolsa. Una vez que se han establecido las dos conexiones, el cliente envía un símbolo de cotización al servidor mediante el canal de comandos y espera a que la cotización a volver a través del canal de datos. Envía la siguiente solicitud de símbolo de cotización al servidor sólo después de que se ha recibido la primera cotización en bolsa. El cliente y el servidor no establecen la opción FTP y TCP_NODELAY.

Rendimiento:

Durante las pruebas, el desarrollador busca que el cliente sólo puede obtener cotizaciones de cinco por segundo.

Análisis:

Este diseño permite sólo una solicitud de cotización de acciones pendientes a la vez. El primer símbolo del valor se envía al servidor mediante el canal de comandos (conexión) y se envía una respuesta inmediatamente desde el servidor al cliente por el canal de datos (conexión). A continuación, el cliente envía inmediatamente la segunda solicitud de símbolo de cotización y el envío se devuelve inmediatamente como el búfer de solicitud en la llamada de envío se copia en el búfer de núcleo de Winsock. Sin embargo, la pila TCP de cliente no puede enviar la solicitud de su búfer núcleo inmediatamente porque la primera enviar a través del canal de comandos no es reconocido todavía. Temporizador al retraso de los 200-ms caduca el canal de comandos de servidor, la confirmación para la primera solicitud de símbolo vuelve al cliente. A continuación, la segunda solicitud de cotización es enviada al servidor después de retraso de 200-ms. que la oferta para el segundo símbolo vuelve inmediatamente a través del canal de datos porque, en este momento, ha caducado el temporizador de retardo en el canal de datos de cliente. El servidor recibe una confirmación de la respuesta del presupuesto anterior. (Recuerde que el cliente no pudo enviar una segunda solicitud de cotización para ms-200, lo que da tiempo para el temporizador de retardo en el cliente para caducar y envíe una confirmación al servidor). Como resultado, el cliente obtiene la segunda respuesta de oferta y puede emitir otra solicitud de presupuesto, que es objeto el mismo ciclo.

Cómo mejorar:

El diseño de la conexión de dos (canal) es necesario aquí. Si utiliza sólo una conexión para la solicitud de cotización y la respuesta, la confirmación de la solicitud de cotización puede se superpone en la respuesta de la oferta y vuelve inmediatamente. Para mejorar aún más el rendimiento, el cliente pudo "multiplexación" varias solicitudes de cotización de acciones en una llamada de envío en el servidor y el servidor podría también "multiplexación" varias respuestas de oferta en una llamada de envío al cliente. Si el diseño de dos canales unidireccional es realmente necesario por algún motivo, ambos lados deben establecer la opción TCP_NODELAY para que los paquetes pueden enviarse inmediatamente sin tener que esperar una confirmación ACK para el paquete anterior.

Recomendaciones:

Aunque se fabrican estos dos casos prácticos, ayudan a ilustrar algunas situaciones. Al diseñar una aplicación que implica el segmento de datos pequeño extensa envía y recvs, se deben tener en cuenta las siguientes directrices:
  • Si los datos son segmentos de tiempo no crítica, la aplicación debe unirse en un bloque de datos mayor para pasar a una llamada de envío. Como el búfer de envío es probable que se copian en el búfer de núcleo de Winsock, el búfer no debe ser demasiado grande. Un poco menos de 8K normalmente es eficaz. Como el núcleo de Winsock Obtiene un bloque mayor que la MTU, enviará varios paquetes de tamaño completo y un último paquete con lo que queda. El lado envío, excepto el último paquete, no se alcanzarán por el temporizador de retardo de 200 ms. El último paquete, si resulta ser un paquete impares, es el algoritmo de confirmación retardada. Si la pila final remitente obtiene otro bloque mayor que la MTU, todavía puede omitir el algoritmo de Nagle.
  • Si es posible, evite las conexiones de socket con el flujo de datos unidireccional. Comunicaciones a través de sockets unidireccionales son afectados por el Nagle con mayor facilidad y retrasa los algoritmos de reconocimiento. Si la comunicación sigue una solicitud y un flujo de respuesta, debe utilizar un único zócalo para envíos y recvs que puede se superpone la confirmación en la respuesta.
  • Si deban de todos los segmentos de datos pequeños se envíen inmediatamente, establezca la opción TCP_NODELAY en el extremo emisor.
  • A menos que desee garantizar que se envía un paquete en la red cuando una finalización del envío se indica mediante Winsock, no debe establecer el FTP a cero. De hecho, el búfer de 8K por defecto se heurísticamente determinó que funcionan bien para la mayoría de las situaciones y no debe cambiarse a menos que se haya probado que la nueva configuración de búfer de Winsock proporciona un mejor rendimiento que el valor predeterminado. También, en su mayor parte es beneficioso para las aplicaciones que la transferencia de datos de forma masiva FTP al establecer en cero. Incluso entonces, para una eficacia máxima debería utilizarlo junto con doble almacenamiento en búfer (más de un envío pendiente en un momento dado) y E/S superpuesta.
  • Si la entrega de datos no tiene que ser garantizada, utilice UDP.
Referencias
Para obtener más información acerca de la confirmación retrasada y el algoritmo de Nagle, consulte lo siguiente:

Braden, R. [1989], RFC 1122, requisitos para Internet Hosts - Communication Layers, Internet Engineering Task Force.

Advertencia: este artículo se tradujo automáticamente

Propiedades

Id. de artículo: 214397 - Última revisión: 03/14/2015 06:12:00 - Revisión: 4.0

  • kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock kbmt KB214397 KbMtes
Comentarios
did=1&t=">