Red de conocimiento del abogados - Conocimiento de la marca - Folleto loco de Java: uso de NIO para implementar comunicación Socket sin bloqueo (1)

Folleto loco de Java: uso de NIO para implementar comunicación Socket sin bloqueo (1)

Utilice NIO para implementar comunicación Socket sin bloqueo

A partir del JDK, Java proporciona la API NIO para desarrollar servidores de red de alto rendimiento. El programa de comunicación de red presentado anteriormente es instantáneo. Programa basado en la API de bloqueo Después de realizar operaciones de entrada y salida, el hilo se bloqueará hasta que estas operaciones regresen, por lo que el servidor debe proporcionar un hilo independiente para cada cliente para su procesamiento. Al mismo tiempo, este enfoque provocará una degradación del rendimiento. Cuando utilice la API de NIO, puede permitir que el servidor utilice uno o un número limitado de subprocesos para procesar todos los clientes conectados al servidor al mismo tiempo.

Si el lector ha olvidado el concepto y el uso de API como Channel Buffer Charset en NIO, puede leer nuevamente el Capítulo 1 de este libro, Capítulo sobre el contenido del nuevo IO.

NIO de Java proporciona el siguiente especial. clases para comunicación Socket sin bloqueo

Selector: Es un multiplexor del objeto SelectableChannel. Los canales que deseen comunicarse de manera sin bloqueo deben registrarse con el objeto Selector. Puede crear una instancia de Selector. llamando al método estático open() de esta clase. Este método utilizará el Selector predeterminado del sistema para devolver un nuevo Selector.

El selector puede monitorear el estado de IO de múltiples SelectableChannels en el. Al mismo tiempo, que es el núcleo de IO sin bloqueo. Una instancia de Selector tiene una colección de SelectionKeys.

Todas las colecciones de SelectionKey representan el canal registrado en el Selector. La colección se puede devolver a través del método claves ().

La colección SelectionKey seleccionada representa todos los canales que se pueden monitorear a través del método select() y requieren procesamiento IO. Esta colección se puede devolver a través de selectedKeys()

La colección SelectionKey cancelada representa. todos los canales cuyas relaciones de registro hayan sido canceladas. Las SelectionKeys correspondientes a estos canales se eliminarán por completo la próxima vez que se ejecute el método select(). Los programas generalmente no necesitan acceder directamente a la colección

Además de. este selector también proporciona una serie de métodos relacionados con select() como se muestra a continuación

int select() monitorea todos los canales registrados. Cuando hay operaciones de IO que deben procesarse entre ellos, este método regresa y el. SelectionKey correspondiente Este método devuelve el número de estos canales cuando se agregan a la colección SelectionKey seleccionada

int select (tiempo de espera prolongado) La operación select() que puede establecer el período de tiempo de espera

int selectNow () ejecuta un inmediato En comparación con el método select() sin parámetros, la operación select() devuelta no bloquea el hilo

El selector wakeup() hace que un método select() que aún no ha regresado regrese inmediatamente

SelectableChannel: representa un objeto de canal que puede admitir operaciones de IO sin bloqueo y se puede registrar en el Selector. Esta relación de registro está representada por la instancia de SelectionKey

El objeto Selector proporciona. un método select() Este método permite que las aplicaciones monitoreen múltiples canales IO simultáneamente.

el

La aplicación puede llamar al método de registro () de SelectableChannel para registrarlo en el Selector especificado. Cuando hay operaciones IO que deben procesarse en algunos SelectableChannels en el Selector, el programa puede llamar a select. () de la instancia Selector para obtener Su número se puede devolver a través del método selectedKeys() a su colección SelectKey correspondiente. A través de esta colección, puede obtener todos los conjuntos de SelectableChannel que necesitan manejar operaciones IO

El. El objeto SelectableChannel admite modos de bloqueo y no bloqueo (todos los canales El valor predeterminado es el modo de bloqueo) El modo sin bloqueo debe usarse para utilizar operaciones IO sin bloqueo

SelectableChannel proporciona los dos métodos siguientes para configurar y devolver el estado del modo del canal

SelectableChannel configureBlocking (bloque booleano) establece si se usa el modo de bloqueo

booleano isBlocking() devuelve si el canal está en modo de bloqueo

Diferentes SelectableChannels admiten diferentes operaciones. Por ejemplo, ServerSocketChannel representa un ServerSocket. Solo admite operaciones OP_ACCEPT

SelectableChannel proporciona los siguientes métodos para devolver todas las operaciones que admite

int validOps(): Devuelve. una máscara de bits que indica las operaciones de IO admitidas en este canal

En SelectionKey, se utiliza una constante estática para definir una operación de IO OP_READ ( ) OP_WRITE ( ) OP_CONNECT ( ) OP_ACCEP ( ). cualquiera de estos cuatro valores es igual al resultado de la suma, y ​​cualquiera de ellos Los resultados de cada suma siempre son diferentes entre sí, por lo que el sistema puede determinar las operaciones admitidas por SelectableChannel en función del valor de retorno de el método validOps() Por ejemplo, al regresar, sabemos que admite lectura ( ) y escritura ( )

Además de esto, SelectableChannel también proporciona los siguientes métodos para obtener su estado de registro. /p>

Boolean isRegistered() devuelve si el canal se ha registrado en uno o más selectores

SelectionKey keyFor(Selector sel) Devuelve la relación de registro entre el canal y el selector sel. relación de registro, devuelve nulo

SelectionKey: este objeto representa la relación de registro entre SelectableChannel y Selector

ServerSocketChannel: admite operaciones sin bloqueo correspondientes a java net ServerSocket. Esta clase proporciona el protocolo TCP. Interfaz IO y solo admite operaciones OP_ACCEPT. Esta clase también proporciona el método aceptar (), que es equivalente al método aceptar () proporcionado por ServerSocket

SocketChannel: admite operaciones sin bloqueo. net Socket. Esta clase proporciona la interfaz IO del protocolo TCP y admite operaciones OP_CONNECT, OP_READ y OP_WRITE.

Se implementó la interfaz ByteChannel, la interfaz ScatteringByteChannel y la interfaz GatheringByteChannel, para que pueda leer y escribir objetos ByteBuffer directamente a través de SocketChannel

La figura muestra un diagrama esquemático del uso de NIO para implementar un servidor sin bloqueo

Figura Diagrama del servidor sin bloqueo NIO

Se puede ver en la figura que todos los canales en el servidor (incluidos ServerSocketChannel y SocketChannel) deben registrarse con el Selector, y el Selector es responsable de monitorear el Estado de IO de estos Sockets Cuando uno o más canales Hay operaciones de IO disponibles, el método select() del Selector devolverá un número entero mayor que 1. El valor entero indica cuántos canales tienen operaciones de IO disponibles en el Selector y proporciona el método selectedKeys() para devolver la SelectionKey correspondiente a estos Canales. La colección utiliza el Selector, de modo que el servidor solo necesita llamar continuamente al método select() de la instancia del Selector para saber si todos los Canales actuales tienen operaciones IO que deben procesarse.

Cuando todos los canales registrados en el Selector no son necesarios, el método select() se bloqueará al procesar operaciones IO. El hilo que llama a este método está bloqueado.

Este programa de muestra utiliza NIO. Para implementar la función de una sala de chat de varias personas, el servidor utiliza un bucle para obtener continuamente el método select () del valor de retorno: cuando el valor de retorno es mayor que el valor, el canal correspondiente a la clave de selección seleccionada. se procesa el Selector

El servidor necesita usar ServerSocketChannel para monitorear la solicitud de conexión del cliente. El diseño de esta clase en Java es deficiente y no es una abstracción completa, por lo que el canal no se puede monitorear directamente. en un puerto determinado, y no se permite el uso del método getChannel () de ServerSoceket para obtener una instancia de ServerSocketChannel. El programa primero debe llamar a su método socket () para obtener el objeto ServerSocket asociado y luego usar el objeto ServerSocket para vincularse. al monitor especificado Para crear un ServerSocketChannel disponible usando IP y puerto, debe usar el siguiente fragmento de código

//Abra una instancia de ServerSocketChannel independiente a través del método abierto

Servidor ServerSocketChannel. = ServerSocketChannel open()

p>

InetSocketAddress isa = new InetSocketAddress ( )

// Vincula ServerSocketChannel a la dirección IP especificada

server socket () bind (isa)

Si necesita utilizar una forma sin bloqueo para manejar ServerSocketChannel, también debe configurar su modo sin bloqueo y registrarlo con el Selector especificado. El siguiente fragmento de código

.

//Configurar ServerSocket para que funcione sin bloqueo

server configureBlocking(false)

//Registrar el servidor en el objeto Selector especificado

ser

ver registrarse (selector SelectionKey OP_ACCEPT)

? Volver al directorio Folletos locos de Java

? ¿La optimización del rendimiento del programa Java hace que su programa Java sea más rápido y Estable más eficiente

¿Los novatos aprenden programación Java lishixinzhi/Article/program/Java/hx/201311/27263