SelectorServerChannel 类: public class SelectorServerChannel { private Selector selector; private ServerSocketChannel serverSocketChannel = null; private int keys = 0 ; public static void main(String[] args) { new SelectorServerChannel().start(); } private void start() { try { SelectorServerChannel selectorServerChannel = new SelectorServerChannel(); // 1- 启动服务 selectorServerChannel.initServer(); // 2- 监听 selectorServerChannel.listen(); } catch (Exception e) { } } private void listen() throws Exception { System.out.println("服务器已经启动成功......"); while (true){ keys = selector.select(); if ( keys > 0 ) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while ( iterator.hasNext() ){ SelectionKey key = iterator.next(); iterator.remove(); //处理 processHander(key); } } } } private void processHander(SelectionKey key) throws Exception{ if ( null == key ) { return; } if ( key.isAcceptable() ) { processAccept(key); } if ( key.isReadable() ) { processRead(key); } } private void processRead(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); // 缓冲区 ByteBuffer buff = ByteBuffer.allocate(1024); CharBuffer charBuff = CharBuffer.allocate(1024); buff.clear(); int len = channel.read(buff); String msg = "服务器收到信息: " + new String(buff.array(),0,len); buff.flip(); System.out.println(msg); } private void processAccept(SelectionKey key) throws IOException { serverSocketChannel = (ServerSocketChannel) key.channel(); // 获取和客户端连接的通道 SocketChannel channel = serverSocketChannel.accept(); // 给客户端通道设置为非阻塞 channel.configureBlocking(false); ByteBuffer buffer = ByteBuffer.wrap("欢迎你连接".getBytes()); channel.write(buffer); //把客户端通道注册到selector channel.register(selector,SelectionKey.OP_READ); } private void initServer() throws IOException { //1- 打开一个通道 serverSocketChannel = ServerSocketChannel.open(); // 2- 获取选择器 selector = Selector.open(); // 3- 绑定通道的端口号 serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1",8888)); // 4- 设置通道为非阻塞 serverSocketChannel.configureBlocking(false); // 5- 注册这个通道 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } }
SelectorClientChannel 类:
public class SelectorClientChannel { private Selector selector; private ByteBuffer outBuff = ByteBuffer.allocate(1024); private CharBuffer outCharBuff = CharBuffer.allocate(1024); private ByteBuffer inBuff = ByteBuffer.allocate(1024); private CharBuffer inCharBuff = CharBuffer.allocate(1024); private int keys = 0 ; private SocketChannel channel = null; public static void main(String[] args) throws IOException { new SelectorClientChannel().start(); } private void start() throws IOException { initClient(); listen(); } private void listen() throws IOException { while (true){ keys = selector.select(); if ( keys > 0 ) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while(iterator.hasNext()){ SelectionKey key = iterator.next(); // 处理 processHander(key); } } } } private void processHander(SelectionKey key) throws IOException { if ( key.isConnectable() ) { SocketChannel channel = (SocketChannel) key.channel(); if ( channel.isConnectionPending() ) { channel.finishConnect(); System.out.println("完成连接!"); } channel.register(selector,SelectionKey.OP_WRITE); } if ( key.isWritable() ) { SocketChannel channel = (SocketChannel) key.channel(); outBuff.clear(); System.out.println("客户端正在写数据..."); outBuff = ByteBuffer.wrap("我是Tom1".getBytes()); channel.write(outBuff); channel.register(selector,SelectionKey.OP_READ); System.out.println("客户端写数据完成。"); } if ( key.isReadable() ) { SocketChannel channel = (SocketChannel) key.channel(); inBuff.clear(); System.out.println("客户端正在读数据..."); int len = channel.read(inBuff); System.out.println(">>>>>" + new String(inBuff.array(),0,len)); System.out.println("客户端读取数据完成!"); } } private void initClient() throws IOException { //1- 获取一个socket通道, channel = SocketChannel.open(); //2- 获取一个选择器 selector = Selector.open(); //3- 通道设置为非阻塞 channel.configureBlocking(false); //4- 连接服务器 //channel.socket().connect(new InetSocketAddress("127.0.0.1",8888)); channel.connect(new InetSocketAddress("127.0.0.1",8888)); //4- 注册通道 channel.register(selector, SelectionKey.OP_CONNECT); } }