2009-02-20 10 views
14

TCP/IP SocketChannels y Selector no bloqueantes en NIO me ayudan a manejar muchas conexiones TCP/IP con un número pequeño de subprocesos. Pero ¿qué hay de UDP DatagramChannels? (Debo admitir que no estoy muy familiarizado con UDP.)E/S UDP no bloqueante frente a E/S UDP bloqueante en Java

Las operaciones de envío UDP no parecen bloquearse incluso si el DatagramChannel no está operando en modo de bloqueo. ¿Hay realmente un caso donde DatagramSocket.send (DatagramPacket) bloquea debido a la congestión o algo similar? Tengo mucha curiosidad si existe un caso así y cuáles son los posibles casos en un entorno de producción.

Si DatagramSocket.send (DatagramPacket) en realidad no bloquea y no voy a usar un DatagramSocket conectado y enlazar a un solo puerto, ¿no hay ninguna ventaja de utilizar el modo no-bloqueo con DatagramChannel y Selector?

Respuesta

12

Ha pasado un tiempo desde que utilicé DatagramSockets de Java, canales y similares, pero aún puedo darte algo de ayuda.

El protocolo UDP no establece una conexión como TCP. Por el contrario, simplemente envía los datos y se olvida de ellos. Si es importante asegurarse de que los datos realmente lleguen allí, esa es la responsabilidad del cliente. Por lo tanto, incluso si se encuentra en el modo de bloqueo, su operación de envío solo se bloqueará durante el tiempo que sea necesario para eliminar el búfer. Como UDP no sabe nada de la red, la escribirá a la mayor brevedad posible sin verificar la velocidad de la red o si realmente llega a donde se supone que irá. Por lo tanto, para usted, parece que el canal está listo de inmediato para enviar más.

+1

¿Qué pasaría si el buffer del kernel es inundado por escrituras demasiado rápidas en un socket UDP? – trustin

+0

Su escritura (de nivel de usuario) se bloquearía hasta que el núcleo se vacíe y los sockets envíen el búfer. – JLR

+7

Por lo tanto, existe una diferencia obvia entre sockets UDP bloqueadores y no bloqueantes, al igual que la diferencia entre los sockets TCP bloqueadores y los no bloqueantes. Escribí un cliente PoC simple y confirmé que el envío del canal UDP sin bloqueo() a menudo devuelve 0, mientras que el bloqueo nunca devuelve 0. ¡Gracias! – trustin

8

UDP no bloquea (solo bloquea mientras está transfiriendo los datos al sistema operativo) Esto significa que si en algún momento el siguiente salto/conmutador/máquina no puede almacenar el paquete UDP, lo descarta. Esto puede ser un comportamiento deseable en algunas situaciones. Pero es algo de lo que debes estar consciente.

UDP no garantiza también a

  • paquetes de entrega en el orden en que se envían.
  • para no romper paquetes grandes.
  • reenviar paquetes a través de interruptores. A menudo, el reenvío UDP entre conmutadores está desactivado.

Sin embargo, UDP admite multidifusión por lo que el mismo paquete se puede entregar a uno o más hosts. Sin embargo, el remitente no tiene idea de si alguien recibe los paquetes.

Una cosa complicada sobre el UDP es que funciona la mayor parte del tiempo, pero falla mucho a veces en formas que son muy difíciles de reproducir. Por esta razón, no debe asumir la fiabilidad incluso si realiza algunas pruebas y parece que funciona.

0

No bloqueando UDP es principalmente útil en el lado de recepción. El envío de paquetes solo se puede demorar debido a circunstancias locales: herramientas de configuración de tráfico como "tarjetas de red de juegos" que priorizan el tráfico de juegos sobre otras fuentes de tráfico o tarjetas de red sobrecargadas (lo que probablemente no ocurra) pueden retrasar el envío de un paquete . Una vez fuera del sistema. Una vez que el paquete sale de la interfaz local, ya no es la preocupación de la aplicación.

Cuestiones relacionadas