socket programming programing geeksforgeeks example c++ windows linux network-programming udp

c++ - programming - socket udp example



¿Cuál es el tamaño óptimo de un paquete UDP para un rendimiento máximo? (9)

Necesito enviar paquetes de un host a otro a través de una red potencialmente con pérdidas . Para minimizar la latencia de paquetes, no estoy considerando TCP / IP. Pero, deseo maximizar el rendimiento usando UDP. ¿Cuál debería ser el tamaño óptimo de paquete UDP para usar?

Estas son algunas de mis consideraciones:

  • El tamaño MTU de los switches en la red es 1500. Si uso un paquete grande, por ejemplo 8192, esto causará fragmentación. La pérdida de un fragmento dará como resultado la pérdida del paquete completo, ¿verdad?

  • Si uso paquetes más pequeños, incurriré en la sobrecarga del encabezado UDP e IP

  • Si uso un paquete realmente grande, ¿cuál es el más grande que puedo usar? Leí que el tamaño de datagrama más grande es 65507. ¿Cuál es el tamaño del buffer que debería usar para permitirme enviar tales tamaños? ¿Eso ayudaría a aumentar mi rendimiento?

  • ¿Cuál es el tamaño de datagrama máximo típico admitido por los sistemas operativos comunes (por ejemplo, Windows, Linux, etc.)?

Actualizado:

Algunos de los receptores de los datos son sistemas integrados para los que no se implementa la pila TCP / IP.

Sé que este lugar está lleno de personas que son muy firmes sobre el uso de lo que está disponible. Pero espero tener mejores respuestas que solo centrarme solo en MTU.


Aunque la MTU en el conmutador es 1500, puede tener situaciones (como la creación de un túnel a través de una VPN) que envuelven unos pocos encabezados adicionales alrededor del paquete; puede ser mejor que los reduzca un poco, y vaya a 1450 más o menos.

¿Se puede simular la red y probar el rendimiento con diferentes tamaños de paquetes?


Bueno, tengo una respuesta que no es MTU para ti. Usar un socket UDP conectado debería acelerar las cosas para usted. Hay dos razones para llamar a connect en su socket UDP. El primero es la eficiencia. Cuando se llama a sendto en un socket UDP desconectado, lo que sucede es que el kernel conecta el socket temporalmente, envía los datos y luego los desconecta. Leí acerca de un estudio que indica que esto implica casi el 30% del tiempo de procesamiento al enviar. La otra razón para llamar a connect es para que pueda obtener mensajes de error ICMP. En un socket UDP desconectado, el kernel no sabe para qué aplicación entregar los errores ICMP, por lo que simplemente se descarta.


El "Stack" es (TCP usa (usos de UDP (IPv4 usa (ETHERNET)))) ... o "Stack" es (TCP usa (usa UDP (IPv6 usa (ETHERNET)))) ...

Todos esos encabezados se agregan en TCP. IPv6 es tonto. Cada computadora no requiere su propia IP. IPv6 es simplemente un problema de paquetes no deseado. Tienes más de 65,000 puertos, no los usarás todos, nunca ... Añádelo a la dirección MAC de la máquina individual en el encabezado ETHERNET, y tienes miles de millones de direcciones.

Enfóquese en (el UDP usa (IPv4 usa (ETHERNET))) encabezados, y todo estará bien. Su programa debería poder "Verificar" el tamaño del paquete, al recibir un búfer de 65,000 bytes sobre UDP, establecer como NULL CHR (0) y enviar un paquete de 65,000 CHR (255) bytes. Puede ver si sus datos UDP se perdieron, porque nunca los obtendrá. Será interrumpido. UDP no transmite paquetes múltiples. Usted envía uno, obtiene uno. Solo obtienes menos si no cabe. O no obtienes nada, si se cae.

TCP mantendrá sus conexiones en el purgatorio hasta que se reciban todos los datos. Está utilizando paquetes UDP e indica a la otra computadora que vuelva a enviar esos paquetes faltantes. Eso viene con gastos indirectos adicionales, y causa un LAG si algún paquete se pierde, se pierde, se agota o se descompone.

UDP le da control total. Use UDP si envía datos "Críticos" y "No Críticos", y desea utilizar un sistema de números de pedido de paquetes reducido, que no depende de la llegada secuencial. Solo use TCP para datos sólidos WEB o SECURE, que requiera persistencia y una integridad del 100%. De lo contrario, solo está desperdiciando nuestro ancho de banda web y agregando desorden inflado a la red. Cuanto menor sea su flujo de datos, menos perderá en el camino. Utilice TCP, y garantizará un LAG adicional relacionado con todos los encabezados de reenvío e hinchado que se agregan al encabezado TCP, para "Control de flujo".

En serio, el control de flujo no es tan difícil de administrar, ni es la prioridad, y la detección de datos faltantes. TCP no ofrece nada. Es por eso que se regala de forma gratuita. No es sazonado, es simplemente estúpido y fácil. Es un viejo par de chanclas. Necesitas un buen par de zapatillas. TCP era, y sigue siendo, un truco.


El encabezado IP es> = 20 bytes pero principalmente 20 y el encabezado UDP es de 8 bytes. Esto te deja 1500 - 28 = 1472 bytes para tus datos. El descubrimiento PATH MTU encuentra la MTU más pequeña posible en el camino hacia el destino. Pero esto no significa necesariamente que, cuando use la MTU más pequeña, obtendrá el mejor rendimiento posible. Creo que la mejor manera es hacer un punto de referencia. O tal vez no deberías preocuparte por el MTU más pequeño en el camino. Un dispositivo de red puede muy bien usar una MTU pequeña y también transferir paquetes muy rápido. Y su valor bien puede cambiar en el futuro. Por lo tanto, no puede descubrir esto y guardarlo en algún lugar para usarlo más adelante, debe hacerlo periódicamente. Si yo fuera tú, establecería el MTU en algo así como 1440 y compararía la aplicación ...


La mejor forma de encontrar el tamaño de datagrama ideal es hacer exactamente lo que TCP hace para encontrar el tamaño de paquete ideal: descubrimiento MTU de ruta .

TCP también tiene una opción ampliamente utilizada en la que ambos lados le dicen al otro cuál es su MSS (básicamente, MTU menos encabezados).


La solución más fácil para encontrar mtu en c # es enviar paquetes udp con el indicador dontfragment establecido en true. si arroja una excepción, intente reducir el tamaño del paquete. haz esto hasta que no haya una excepción lanzada. puede comenzar con 1500 paquetes de tamaño.


Respuesta alternativa: tenga cuidado de no reinventar la rueda.

TCP es el producto de décadas de experiencia en redes. Hay un reson para cada cosa o casi todo lo que hace. Tiene varios algoritmos que la mayoría de la gente no piensa con frecuencia (control de congestión, retransmisión, administración de búfer, manejo de paquetes reordenados, etc.).

Si comienzas a reimplementar todos los algoritmos TCP, te arriesgas a terminar con una (parafatizando la Décima Regla de Greenspun ) "ad hoc, especificada informalmente, basada en errores, lenta implementación de TCP".

Si aún no lo ha hecho, podría ser una buena idea mirar algunas alternativas recientes a TCP / UDP, como SCTP o DCCP. Fueron diseñados para nichos donde ni TCP ni UDP eran una buena combinación, precisamente para permitir a las personas usar un protocolo ya "depurado" en lugar de reinventar la rueda para cada nueva aplicación.


Uhh Jason, TCP no usa UDP. TCP usa IP, por lo que a menudo se lo ve como TCP / IP. UDP también usa IP, por lo que UDP es técnicamente UDP / IP. La capa IP maneja la transferencia de datos de un extremo a otro (a través de diferentes redes), por lo que se denomina Protocolo de interfuncionamiento de redes . TCP y UDP manejan la segmentación de los datos en sí. Las capas inferiores, como Ethernet o PPP, o cualquier otra cosa que utilice, manejan la transferencia de datos de computadora a computadora (es decir, dentro de una sola red).


Otra cosa a considerar es que algunos dispositivos de red no manejan la fragmentación muy bien. Hemos visto muchos enrutadores que lanzan paquetes UDP fragmentados o paquetes que son demasiado grandes. La sugerencia de CesarB de utilizar Path MTU es buena.

El rendimiento máximo no está determinado solo por el tamaño del paquete (aunque esto contribuye por supuesto). Minimizar la latencia y maximizar el rendimiento a menudo están en desacuerdo entre sí. En TCP tiene el algoritmo Nagle que está diseñado (en parte) para aumentar el rendimiento general. Sin embargo, algunos protocolos (por ejemplo, Telnet) a menudo desactivan Nagle (es decir, establecen el bit Sin Demora) para mejorar la latencia.

¿Tiene algunas limitaciones de tiempo real para los datos? La transmisión de audio es diferente a presionar datos no en tiempo real (por ejemplo, información de registro) ya que el primero se beneficia más de la baja latencia, mientras que el último se beneficia de un mayor rendimiento y tal vez de confiabilidad. ¿Hay requisitos de confiabilidad? Si no puede perder paquetes y tiene que tener un protocolo para solicitar la retransmisión, esto reducirá el rendimiento general.

Hay una miríada de otros factores que intervienen en esto y (como se sugirió en otra respuesta) en algún momento se obtiene una mala implementación de TCP. Dicho esto, si desea alcanzar una baja latencia y puede tolerar la pérdida usando UDP con un tamaño de paquete general establecido en el PATH MTU (asegúrese de establecer el tamaño de la carga útil para tener en cuenta los encabezados) es probablemente la solución óptima (especialmente si puede asegurar que UDP pueda pasar de un extremo a otro.