c++ sockets boost tcp boost-asio

c++ - Boost:: ASIO: optimice para tráfico mínimo, conexión larga, mensajes pequeños, pasados instantáneamente



sockets tcp (1)

Estoy escribiendo un protocolo en Boost :: ASIO que tiene los siguientes requisitos:

  1. Las conexiones son duraderas y deberían usar la menor sobrecarga posible para "mantenerse con vida".
  2. Los mensajes son pequeños y se deben pasar al instante.

¿Hay otros indicadores de socket TCP o configuración Boost :: ASIO que debo usar?

socket_.set_option(boost::asio::ip::tcp::no_delay(true)); // enable PSH socket_.set_option(boost::asio::socket_base::keep_alive(true)); // enable SO_KEEPALIVE socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPIDLE>(120)); // secs before keepalive probes socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPINTVL>(10)); // interval between keepalive socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPCNT(5)); // failed keepalive before declaring dead


TL; DR : el protocolo manejará lo que se denomina "flujos finos" y están bastante bien documentados, si mi respuesta no es suficiente. La mayor ventaja debe venir de no_delay(true) y lecturas / escrituras async (para el funcionamiento normal) y dupACK y tiempos de espera lineales (para recuperación de fallos). Para obtener más detalles (incluidas las opciones TCP estáticas / del servidor) y comentarios adicionales, consulte a continuación.

En general, me gustaría elegir estas opciones considerando lo siguiente:

  1. ¿Cuál es mi caso de uso ? En su caso, una conexión de larga duración (¿por cuánto tiempo?) A través de la cual se enviarán pequeños mensajes sin almacenamiento en búfer. Se necesita una pequeña huella de mantener viva. Este parece ser el clásico ejemplo de "corrientes finas" .
  2. ¿Cuál sería el mejor protocolo de capa de transporte para usar? https://en.wikipedia.org/wiki/Transport_layer#Protocols - hay un grupo cada uno con sus propios casos de uso. En este punto, supongo que realmente necesita TCP para la confiabilidad y la orientación de la conexión, de lo contrario, los protocolos basados ​​en udp podrían ser mejores (un ejemplo sería UDP-lite, que permite sumas de comprobación parciales y una decisión de confiabilidad subyacente en la capa de aplicación (o la capa que usted, como desarrollador implementaría).
  3. Después de haber elegido el protocolo subyacente en el que quiero construir, investigue las opciones de ajuste 4 de ese protocolo. Para TCP esos son:

    • Algoritmo de Nagle: almacenamiento de datos, usted lo apagó correctamente.
    • ACK retrasado: combina ACK, útil para aplicaciones similares a telnet, donde no es necesario enviar ACK para cada carácter transmitido. TCP_QUICKACK si necesita lo contrario - ACK se envía inmediatamente. En caso de que envíes datos muy raramente puede ser útil.
    • Sondas de actividad: veo que usa valores bastante cortos. No estoy seguro de cómo decidió esos valores en particular, pero podría considerar extenderlos, para mantener "la sobrecarga mínima posible para" mantener vivo ". Los valores predeterminados para Linux: 7200, 75, 9.
    • Indicador PSH: útil para la comprensión, en gran parte no utilizado / ignorado / irrelevante.
    • Indicador URG: reenvía los datos urgentes en un canal separado a la aplicación, útil si planea recibir datos fuera de banda (algunos datos de control, como la cancelación). Probablemente no sea útil en su caso, ya que hay poco espacio para los datos OOB en caso de "flujos finos".
    • TCP de Windows (RWND / CWND): no se aplica a mensajes pequeños que rara vez se envían. Las ventanas deberían ser suficientes para acomodar los datos.
    • Tamaño de la ventana después de inactividad (SSR): Not surprisingly, SSR can have a significant impact on performance of long-lived TCP connections that may idle for bursts of time — eg, due to user inactivity. As a result, it is generally recommended to disable SSR on the server to help improve performance of long-lived HTTP connections. Not surprisingly, SSR can have a significant impact on performance of long-lived TCP connections that may idle for bursts of time — eg, due to user inactivity. As a result, it is generally recommended to disable SSR on the server to help improve performance of long-lived HTTP connections. Tomado de here . La opción: sysctl -w tcp_slow_start_after_idle=0
    • Transmisión rápida de TCP: tcp_thin_dupack debe estar activado. Reduce el tiempo que un remitente espera antes de retransmitir un segmento perdido. Tenga cuidado de leer y experimentar con las precauciones (se pueden especificar por zócalo, vea el punto inmediatamente).
    • tcp_thin_linear_timeouts : esto permite una recuperación más rápida en la pérdida de paquetes, se puede especificar por socket: https://nnc3.com/mags/LJ_1994-2014/LJ/219/11180.html
    • TFO_FASTOPEN (TFO): - acorta el establecimiento de conexión inicial. No es muy aplicable para conexiones de larga duración, pero podría considerarse.
    • Compresión: de acuerdo con la información que veo, no debe usarse en su caso (no es una opción de TCP, se puede agregar en la parte superior de TCP) ya que agregará latencia que creo que está evitando. Añadiendo estas opciones en caso de que no sea cierto.
  4. Algunos detalles de la infraestructura que la aplicación debe manejar o la documentación del protocolo podría especificar.

    • Para conexiones duraderas si son terminadas por el lado del servidor, el estado TIME_WAIT será importante. El lado que inicia la terminación de la conexión incurre en la penalización de TIME_WAIT, por lo que, dependiendo del uso de su aplicación / protocolo, esto podría ser una consideración. Esto depende de cómo manejará la terminación de la conexión.
    • Puertos efímeros: tal vez sea útil aumentar la cantidad de puertos efímeros para acomodar esas conexiones duraderas, no estoy seguro. Este es un posible punto de viñeta de documentación para su protocolo.

Si su protocolo está sintonizado para telnet como comunicación, puede ver esta implementación de telnet. Básicamente está lleno de escrituras y lecturas asíncronas: https://lists.boost.org/boost-users/att-40895/telnet.cpp

Algunas buenas lecturas:

https://www.extrahop.com/company/blog/2016/tcp-nodelay-nagle-quickack-best-practices/ https://sourceforge.net/p/asio/mailman/asio-users/?page=257 - Para ayuda adicional.