¿Cómo estrangulas el ancho de banda de una conexión de socket en C?

Estoy escribiendo una aplicación cliente-servidor usando sockets BSD. Debe ejecutarse en segundo plano, transfiriendo continuamente datos, pero no puede mantener el ancho de banda de la interfaz de red del uso normal. Dependiendo de la velocidad de la interfaz, necesito acelerar esta conexión a una determinada velocidad de transferencia máxima.

¿Cuál es la mejor manera de lograr esto, programáticamente?

El problema de dormir una cantidad constante de 1 segundo después de cada transferencia es que tendrá un rendimiento de red agitado.

Deje BandwidthMaxThreshold como el umbral de ancho de banda deseado.

Deje TransferRate ser la velocidad de transferencia actual de la conexión.

Entonces…

Si detecta TransferRate> BandwidthMaxThreshold, realiza SleepTime = 1 + SleepTime * 1.02 (aumenta el tiempo de espera en un 2%)

Antes o después de cada operación de la red, haga una suspensión (SleepTime)

Si detecta que TransferRate es mucho más bajo que BandwidthMaxThreshold, puede disminuir su SleepTime. Alternativamente, usted podría simplemente disminuir / disminuir su SleepTime con el tiempo siempre. Finalmente, su SleepTime alcanzará 0 nuevamente.

En lugar de un aumento del 2%, también podría hacer un aumento en una cantidad mayor linealmente de la diferencia entre TransferRate – BandwidthMaxThreshold.

Esta solución es buena, porque no tendrá sueño si la red del usuario ya no es tan alta como le gustaría.

La mejor manera sería usar un cubo de fichas .

Transmita solo cuando tenga suficientes tokens para completar un paquete (1460 bytes sería una buena cantidad), o si es el receptor, lea desde el socket solo cuando tenga suficientes tokens; un poco de matemática simple te dirá cuánto tiempo tienes que esperar antes de tener suficientes tokens, para que puedas dormir esa cantidad de tiempo (ten cuidado de calcular cuántos tokens ganaste por cuánto dormiste realmente , ya que la mayoría de los sistemas operativos pueden duerma su proceso por más tiempo de lo que pidió).

Para controlar el tamaño de las ráfagas, limite la cantidad máxima de tokens que puede tener; una buena cantidad podría ser un segundo valor de tokens.

He tenido buena suerte con goteo . Es genial porque puede acelerar las aplicaciones de espacio de usuario arbitrarias sin modificaciones. Funciona al precargar sus propias funciones de envoltura send / recv que hacen el cálculo del ancho de banda por usted.

El mayor inconveniente que encontré fue que es difícil coordinar múltiples aplicaciones que desea compartir con ancho de banda finito. “filtrado” ayuda, pero lo encontré complicado.

Actualización en 2017: parece que el goteo se movió a https://github.com/mariusae/trickle