habitaciones de chat de Internet para lograr NIO
1. Selector
Antes de entrar al código, primer vistazo a los selectores: Selector, programación de la red de teléfonos celulares, servidor puede ejecutar un hilo selector de programas en ejecución, escuchando a operar. Su función es comprobar el estado de uno o más canales legibles.
Selector métodos comúnmente utilizados:
- public static Selector Open ();
para dar un objeto seleccionado - int pública seleccionar (tiempo de espera largo);
escuchar a todos los canales registrados, si la presente operación IO arroyos, la información será SelectionKey correspondiente al conjunto de dentro de almacenado, el parámetro es un tiempo de espera - Conjunto pública selectionKeys ();
Devuelve el actual Guardar recolección interna selector de todos los SelectionKey
1.1 SelectionKey
SelectionKey representa canal de red SelectionKey y relación directa
int OP_ACCEPT; 16 necesita ser conectado
OP_CONNECT int; 8 conectado
Int OP_WRITE; 4 escrituras
int OP_READ; 1 operación de lectura
métodos:
- selector Selector resumen público ();
Selector obtenido asociado con el mismo objeto - canal SelectableChannel resumen público ();
resultante canal asociado - fijación de objetos public final ();
datos compartidos obtenidos asociados con los mismos - interestOps públicas abstractos SelectionKey ops (int) ;
para establecer o cambiar los eventos del monitor - isAcceptable public final boolean ();
Puede aceptar - isReadable public final boolean ();
se puede leer - public final boolean isWritable ();
si se puede escribir
1.2 ServerSocketChannel
Toma de programa de servidor correspondiente al canal
método | efecto |
---|---|
public static ServerSocketChannel abierta () | A su vez en el canal ServerSocketChannel servidor |
se unen ServerSocketChannel public final (SocketAddress local); | número de puerto del servidor conjunto |
configureBlocking pública final SelectableChannel (bloque boolean); | Conjunto de bloqueo o modo de no bloqueo, falsa representación no bloqueante |
pública SocketChannel aceptar () | La adquisición de una conexión de cliente, y la operación para obtener el canal correspondiente |
SelectionKey registro público final (selector SEL, ops INT) | Register selector y elija lo monitor de eventos |
1.3 SocketChannel
cliente socket objetos correspondientes al Canal
método | efecto |
---|---|
estática SocketChannel open () | Abrir un objeto Socket canal de cliente |
última SelectableChannel configureBlocking (bloque boolean) | Los ajustes se bloquean o desbloquean |
boolean connect (SocketAddress remoto) | Conectar con el servidor |
boolean finishConnect () | Si se conecta la conexión falla, puede continuar para conectarse a través finishConnect |
final de registro SelectionKey (sel Selector, ops int, attechment Object); | Registrar el SocketChannel, seleccionar un servicio de escucha correspondiente, y puede tener parámetros de fijación de objetos |
close void final () | Cerrar SocketChannel |
2. NIO cliente un completo y el servidor
la parte 2.1 del servidor
public static void main(String[] args) throws IOException {
// 1. 开启服务器
ServerSocketChannel serverSocket = ServerSocketChannel.open();
// 2. 开启Selector
Selector selector = Selector.open();
// 3. 服务端代码绑定端口号
serverSocket.bind(new InetSocketAddress(8848));
// 4. 设置非阻塞状态
serverSocket.configureBlocking(false);
//5. ServerSocketChannel 注册--> Selector 返回值是一个SelectionKey
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
if (0 == selector.select(1000)) {
// 0 == selector.select(1000) 表示没有连接到客户端
continue;
}
Iterator<SelectionKey> selectionKeys = selector.selectedKeys().iterator();
while (selectionKeys.hasNext()) {
SelectionKey selectionKey = selectionKeys.next();
//连接请求
if (selectionKey.isAcceptable()) {
System.out.println("客户端请求连接!!!");
SocketChannel socket = serverSocket.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024 * 4));
}
//可读
if (selectionKey.isReadable()) {
SocketChannel socket = (SocketChannel) selectionKey.channel();
ByteBuffer buffer = (ByteBuffer) selectionKey.attachment();
socket.read(buffer);
System.out.println("客户端发送数据:" + new String(buffer.array()));
}
selectionKeys.remove();
}
}
}
2.2 La parte del cliente
//main方法内
SocketChannel socket = SocketChannel.open();
socket.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress("192.168.1.110", 8848);
//l连接服务器
if (!socket.connect(address)) {
while (!socket.finishConnect()) {
System.out.println("保持呼叫服务器状态,但是我还能做点别的事情~~~ 等待2s继续申请连接~~~");
Thread.sleep(2000);
}
}
//准备一个数据存入到缓冲区
ByteBuffer buffer = ByteBuffer.wrap("你好,服务器,我在等你...".getBytes());
socket.write(buffer);
new Scanner(System.in).nextLine();