tipos socket informatica electrico networking tcp sockets udp

networking - socket - ¿Qué sucede cuando el servidor tcp/udp se publica más rápido de lo que consume el cliente?



tcp socket c++ (6)

Estoy tratando de entender qué sucede cuando un servidor publica (a través de tcp, udp, etc.) más rápido de lo que un cliente puede consumir los datos.

Dentro de un programa, entiendo que si hay una cola entre el productor y el consumidor, comenzará a crecer. Si no hay cola, entonces el productor simplemente no podrá producir nada nuevo, hasta que el consumidor pueda consumir (sé que puede haber muchas más variaciones).

No tengo claro qué sucede cuando los datos salen del servidor (que puede ser un proceso diferente, una máquina o un centro de datos) y se envían al cliente. Si el cliente simplemente no puede responder a los datos entrantes lo suficientemente rápido, suponiendo que el servidor y el consumidor están muy poco conectados, ¿qué sucede con los datos en vuelo?

¿Dónde puedo leer para obtener detalles sobre este tema? ¿Tengo que leer los detalles de bajo nivel de TCP / UDP?

Gracias


Con TCP hay una ventana TCP que se usa para el control de flujo. TCP solo permite que una cierta cantidad de datos permanezcan sin ser reconocidos a la vez. Si un servidor está produciendo datos más rápido de lo que un cliente está consumiendo datos, entonces la cantidad de datos no reconocidos aumentará hasta que la ventana de TCP esté ''llena'' en este punto, la pila de TCP de envío esperará y no enviará más datos hasta que el cliente Reconoce algunos de los datos que están pendientes.

Con UDP no hay tal sistema de control de flujo; no es confiable después de todo Las pilas UDP tanto en el cliente como en el servidor pueden soltar datagramas si así lo desean, al igual que todos los enrutadores entre ellos. Si envía más datagramas de los que el enlace puede entregar al cliente o si el enlace entrega más datagramas de los que su código de cliente puede recibir, algunos de ellos se desecharán. El servidor y el código del cliente probablemente nunca lo sabrán a menos que haya creado algún tipo de protocolo confiable sobre UDP básico. Aunque en realidad es posible que la pila de la red NO descarte los datagramas y que los controladores de la NIC simplemente masticen todo el grupo no paginado disponible y eventualmente bloqueen el sistema (consulte la publicación de este blog para obtener más detalles ).

De vuelta con TCP, la forma en que el código de su servidor se ocupa de que la ventana TCP se llene depende de si está utilizando la E / S de bloqueo, la E / S de no bloqueo o la E / S asíncrona.

  • Si está utilizando el bloqueo de E / S, sus llamadas de envío se bloquearán y su servidor se ralentizará; efectivamente su servidor está ahora en paso de bloqueo con su cliente. No puede enviar más datos hasta que el cliente haya recibido los datos pendientes.

  • Si el servidor utiliza E / S no bloqueantes, es probable que obtenga una devolución de error que le indique que la llamada se habría bloqueado; puede hacer otras cosas pero su servidor deberá reenviar los datos en una fecha posterior ...

  • Si está utilizando E / S asíncrona, entonces las cosas pueden ser más complejas. Por ejemplo, con E / S asíncronas utilizando puertos de finalización de E / S en Windows, no notará nada diferente. Sus envíos superpuestos seguirán siendo aceptados, pero puede notar que se están demorando más en completarse. Los envíos superpuestos se ponen en cola en la máquina de su servidor y están usando la memoria para sus buffers superpuestos y, probablemente, también están usando un "grupo no paginado". Si continúa emitiendo envíos superpuestos, corre el riesgo de agotar la memoria de la agrupación no paginada o de utilizar una cantidad potencialmente ilimitada de memoria como búferes de E / S. Por lo tanto, con la E / S asíncrona y los servidores que PODRÍAN generar datos más rápido de lo que sus clientes pueden consumir, debe escribir su propio código de control de flujo que maneje utilizando las terminaciones de sus escrituras. He escrito sobre este problema en mi blog, here y here y el marco de mi servidor proporciona un código que lo soluciona automáticamente.

En lo que respecta a los datos "en vuelo", las pilas TCP en ambos pares asegurarán que los datos lleguen como se espera (es decir, en orden y sin que falte nada), lo harán reenviando los datos cuando sea necesario.


Con TCP, esto no puede suceder.

En caso de UDP, los paquetes se perderán.


El artículo de Wikipedia sobre TCP muestra el formato del encabezado TCP, que es donde se guardan el tamaño de la ventana y el número de secuencia de confirmación. El resto de los campos y la descripción deben dar una buena visión general de cómo funciona la regulación de la transmisión. RFC 793 especifica las operaciones básicas; Las páginas 41 y 42 detallan el control de flujo.


El servidor no puede ser más rápido que el cliente durante mucho tiempo. Después de que haya sido más rápido que el cliente durante un tiempo, el sistema donde está alojado lo bloqueará cuando escriba en el socket (las escrituras se pueden bloquear en un búfer completo, al igual que las lecturas se pueden bloquear en un búfer vacío).


Si realmente desea comprender TCP, necesita leer una implementación junto con el RFC; Las implementaciones de TCP reales no son exactamente como se especifican. Por ejemplo, Linux tiene un concepto de "presión de memoria" que protege contra la acumulación de memoria DMA del kernel (algo pequeño) y también evita que un socket ejecute cualquier otro espacio de almacenamiento intermedio.


TCP tiene una característica llamada control de flujo .

Como parte del protocolo TCP, el cliente le dice al servidor cuánto más datos se pueden enviar sin llenar el búfer. Si el búfer se llena, el cliente le dice al servidor que aún no puede enviar más datos. Una vez que el búfer se vacía un poco, el cliente le dice al servidor que puede comenzar a enviar datos nuevamente. (Esto también se aplica cuando el cliente está enviando datos al servidor).

UDP por otro lado es completamente diferente. UDP en sí mismo no hace nada como esto y comenzará a eliminar datos si está llegando más rápido que el proceso puede manejar. Correspondería a la aplicación agregar lógica al protocolo de la aplicación si no puede perder datos (es decir, si requiere un flujo de datos "confiable").