java sockets socketchannel

java - Socket vs SocketChannel



sockets (3)

Aunque está utilizando SocketChannels , es necesario emplear el grupo de subprocesos para procesar los channels .

Pensando en el scenairo solo utiliza un hilo que es responsable tanto de select() polling select() como de procesar los SocketChannels seleccionados de Selectors , si un canal tarda 1 segundo para procesarlo, y hay 10 canales en cola, significa que debe esperar 10 segundos antes del próximo sondeo que es intolerable. por lo que debería haber un grupo de subprocesos para el procesamiento de canales.

En este sentido, no veo una tremenda diferencia en el patrón de sockets de bloqueo de hilos por cliente. la principal diferencia está en el patrón NIO , la tarea es más pequeña, es más como hilo por tarea, y las tareas pueden ser leídas, escritas, proceso de trabajo, etc. para más detalles, puede echar un vistazo a la implementación de NioServerSocketChannelFactory de NioServerSocketChannelFactory , que usa una conexión de aceptación de hilos Boss y envía tareas a un grupo de hilos de trabajo para su procesamiento

Si usted es realmente sofisticado en un hilo, al menos cree que tiene subprocesos de E / S agrupados, debido a que las operaciones de E / S suelen ser de una magnitud un poco más lenta que los ciclos de procesamiento de instrucciones, no querría el precioso hilo. está bloqueado por E / S, y esto es exactamente lo que hace NodeJS , usando una conexión de aceptar un hilo, y todas las E / S son asynchornous y son procesadas paralelamente por el grupo de subprocesos de E / S de fondo

¿Está el viejo hilo por cliente muerto? No lo creo, la programación de NIO es compleja y los hilos múltiples no son malos por naturaleza. Tenga en cuenta que los sistemas operativos modernos y las CPU se vuelven cada vez mejores en la multitarea, por lo que los costos generales del multihilo se reducen con el tiempo.

Estoy tratando de entender SocketChannels , y NIO en general. Sé cómo trabajar con sockets regulares y cómo crear un servidor simple de hilos por cliente (usando los sockets de bloqueo habituales).

Entonces mis preguntas:

  • ¿Qué es un SocketChannel?
  • ¿Cuál es el extra que obtengo cuando trabajo con un SocketChannel en lugar de un Socket?
  • ¿Cuál es la relación entre un canal y un buffer?
  • ¿Qué es un selector?
  • La primera instancia en la documentation es A selectable channel for stream-oriented connecting sockets. . Qué significa eso?

He leído también NIO , pero de alguna manera no la obtengo ...


En este momento, NIO es tan viejo que pocos recuerdan cómo era Java antes de 1.4, que es lo que necesita saber para comprender el "por qué" de NIO .

En pocas palabras, hasta Java 1.3, todas las E / S eran del tipo de bloqueo. Y, lo que es peor, no había un análogo de la llamada al sistema select() para la E / S multiplexada. Como resultado, un servidor implementado en Java no tuvo más remedio que emplear una estrategia de servicio de "un hilo por conexión".

El punto básico de NIO, introducido en Java 1.4, era hacer que la funcionalidad de las E / S multiples bloqueadas tradicionales estilo UNIX estuviera disponible en Java. Si comprende cómo programar con select() o poll() para detectar la preparación de E / S en un conjunto de descriptores de archivos (por lo general, sockets), encontrará los servicios que necesita para eso en NIO : utilizará SocketChannel s para puntos finales de E / S sin bloqueo y Selector s para conjuntos de archivos fdsets o pollfd. Los servidores con grupos de subprocesos, o con subprocesos que manejan más de una conexión cada uno, ahora son posibles. Ese es el "extra".

Un Buffer es el tipo de matriz de bytes que necesita para la E / S de socket sin bloqueo, especialmente en el lado de salida / escritura. Si solo se puede escribir inmediatamente una parte de un búfer, bloqueando las E / S, su cadena simplemente bloqueará hasta que se pueda escribir la totalidad. Con E / S sin bloqueo, su hilo obtiene un valor de retorno de cuánto se escribió, dejando que usted maneje el sobrante para la siguiente ronda. Un Buffer se ocupa de tales detalles mecánicos implementando explícitamente un patrón de productor / consumidor para el llenado y drenaje, entendiéndose que sus hilos y el núcleo de la JVM no estarán sincronizados.


Un Socket es un dispositivo de entrada / salida de bloqueo. Hace que el Thread que lo está usando bloquee las lecturas y también bloquea las escrituras si el búfer subyacente está lleno. Por lo tanto, debe crear varios hilos diferentes si su servidor tiene un montón de Socket abiertos.

Un SocketChannel es una forma no bloqueante para leer desde los sockets, de modo que puede hacer que un thread se comunique con un grupo de conexiones abiertas a la vez. Esto funciona agregando un montón de SocketChannel a un Selector , luego haciendo un bucle en el método select() del selector, que puede notificarle si los sockets se han aceptado, recibido o cerrado. Esto le permite comunicarse con múltiples clientes en un hilo y no tener la sobrecarga de varios hilos y la sincronización.

Buffer son otra característica de NIO que le permite acceder a los datos subyacentes de las lecturas y escrituras para evitar la sobrecarga de copiar datos en nuevas matrices.