在对java NIO selector 与 Buffer Channel 有一定的了解之后,我们进行编写java nio 实现的 客户端与服务端例子:
服务端:
public class NIOChatService { private static Map<String,SocketChannel> userMap =new HashMap<>(); public static void main(String[] args) throws Exception { //创建selector 对象 Selector selector =Selector.open(); //创建serverSocketChannel ServerSocketChannel serverSocketChannel =ServerSocketChannel.open(); //设置为非阻塞 serverSocketChannel.configureBlocking(false); //绑定端口 serverSocketChannel.bind(new InetSocketAddress(9999)); //监听客户端的连接事件,绑定在selector 上 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //死循环 while(true) { //阻塞监听,监听是否有事件发生 selector.select(); //获取事件发生的selectionkey Set<SelectionKey> selectedKeys = selector.selectedKeys(); for(SelectionKey key:selectedKeys) { if(key.isAcceptable()) { //如果是客户端的连接的话 ServerSocketChannel serverchannel=(ServerSocketChannel)key.channel(); //获取socketchannel 传输对象 SocketChannel accept = serverchannel.accept(); accept.configureBlocking(false); accept.register(selector, SelectionKey.OP_READ); //保存连接的用户信息 String keys ="{"+UUID.randomUUID()+"}"; userMap.put(keys, accept); System.out.println(userMap); } else if(key.isReadable()) { //只要能进入到可读的,那么channel 一定是SocketChannel SocketChannel socketChannel =(SocketChannel)key.channel(); ByteBuffer bytebuffer =ByteBuffer.allocate(1024); //读取数据到ByteBuffer socketChannel.read(bytebuffer); bytebuffer.flip(); Charset charset =Charset.forName("utf-8"); String receiveMsg=String.valueOf(charset.decode(bytebuffer).array()); for(Map.Entry<String, SocketChannel> entry:userMap.entrySet()) { ByteBuffer bys1 =ByteBuffer.allocate(1024); bys1.put((entry.getKey()+receiveMsg).getBytes()); SocketChannel channel =entry.getValue(); bys1.flip(); channel.write(bys1); } } //一定要进行clear 操作 selectedKeys.clear(); } ; } } }
客户端例子:
public class JavaNioClient { public static void main(String[] args) throws Exception { //建立Selector Selector selector =Selector.open(); SocketChannel socketChannel=SocketChannel.open(); //设置非阻塞 socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999)); while(true) { selector.select(); Set<SelectionKey> setionkey =selector.selectedKeys(); for(SelectionKey kk :setionkey) { if(kk.isConnectable()) { //从selectionkey 获取socketChannel SocketChannel socket=(SocketChannel)kk.channel(); //手动建立连接 if(socket.isConnectionPending()) { socket.finishConnect(); //写数据 ByteBuffer byteB = ByteBuffer.allocate(1024); byteB.put((System.currentTimeMillis()+"连接ok").getBytes()); byteB.flip(); socket.write(byteB); //jdk1.5 线程池 ExecutorService exe =Executors.newSingleThreadExecutor(Executors.defaultThreadFactory()); exe.submit(new Thread() { @Override public void run() { while(true) { String msg=null; byteB.clear(); //标准键盘输入 BufferedReader br =new BufferedReader(new InputStreamReader(System.in)); try { msg =br.readLine(); ByteBuffer bytec = ByteBuffer.allocate(1024); bytec.put(msg.getBytes()); bytec.flip(); socket.write(bytec); } catch (IOException e) { e.printStackTrace(); } } } }); } socket.register(selector, SelectionKey.OP_READ); } else if(kk.isReadable()) { //从selectionkey 获取socketChannel SocketChannel socket=(SocketChannel)kk.channel(); ByteBuffer by =ByteBuffer.allocate(1024); int a=socket.read(by); //if(a>0) { String receive =new String(by.array()); System.out.println(receive); //} } setionkey.clear(); } } } }