2008-10-25 23 views
21

Estoy escribiendo una aplicación cliente-servidor utilizando conectores 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.¿Cómo estrangulas el ancho de banda de una conexión de socket en C?

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

+0

Establezca el tamaño del búfer de recepción del zócalo al producto de retardo de ancho de banda deseado. – EJP

Respuesta

17

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

Sea BandwidthMaxThreshold el umbral de ancho de banda deseado.

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

Entonces ...

Si detecta su TRANSFERRATE> BandwidthMaxThreshold entonces hacer una T. inact = 1 + T. inact * (tiempo de aumento del sueño en un 2%) 1,02

Antes o después de cada operación de la red hacer una Dormir (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.

+0

@Brian: ¿Por qué es '1 +' necesario? ¿No SleepTime = 1.02 * SleepTime por sí mismo aumenta el valor en un 2%? – sundar

+2

Acabo de agregarlo para que, si su SleepTime llega a 0, pueda volver a crecer. También para que siempre crezca por lo menos 1 cuando tiene que crecer. –

+0

Si el protocolo utiliza acuses de recibo, entonces la demora antes de que se reciba una respuesta también se podría usar para proporcionar un retraso de canalización extremo a extremo y sugerir la velocidad a la que se transmiten los mensajes. Esto proporcionaría una solución adaptativa que permitiría el autoajuste en múltiples instalaciones. – Pekka

6

He tenido buena suerte con trickle. 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: se ve como goteo se trasladó a https://github.com/mariusae/trickle

12

La mejor manera sería utilizar un token bucket.

Transmite solo cuando tienes suficientes tokens para completar un paquete (1460 bytes sería una buena cantidad), o si eres el receptor, lee desde el socket solo cuando tienes suficientes tokens; un poco de matemática simple le dirá cuánto tiempo tiene que esperar antes de tener suficientes tokens, por lo que puede dormir esa cantidad de tiempo (tenga cuidado de calcular cuántos tokens ganó por cuánto en realidad durmió, ya que la mayoría de los operativos los sistemas pueden dormir 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.

Cuestiones relacionadas