多路复用器
select
1、select选择器会告诉客户端哪些连接有数据要读取,但是读取的操作还是用户自己触发的,这种叫做「同步」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| package com.ibli.javaBase.nio;
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; import java.util.Set;
public class SelectMultiple {
private ServerSocketChannel server = null; private Selector selector = null; int port = 9090;
public void initServer() throws IOException { server = ServerSocketChannel.open(); server.configureBlocking(false); server.bind(new InetSocketAddress(port)); server.register(selector, SelectionKey.OP_ACCEPT); }
public void start() throws IOException { initServer(); System.err.println("server started ....");
while (true) { while (selector.select() > 0) { Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iter = selectionKeys.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); if (key.isAcceptable()) { acceptHandle(key); } else if (key.isReadable()) { readHandle(key); } }
}
} }
public void acceptHandle(SelectionKey key) throws IOException { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel client = ssc.accept(); client.configureBlocking(false); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024); client.register(selector, SelectionKey.OP_READ, byteBuffer); System.err.println("client arrived " + client.getRemoteAddress()); }
public void readHandle(SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); buffer.clear(); int read = 0; while (true) { read = client.read(buffer); if (read > 0) { buffer.flip(); while (buffer.hasRemaining()) { client.write(buffer); } buffer.clear(); } else if (read == 0) { break; } else { client.close(); break; } } }
}
|
上面的写法是一个selector既担任boss又担任worker