NIO操作

作者: 笑才 | 来源:发表于2019-01-01 17:53 被阅读0次
    public class MyNioServer {
        private Selector selector;//创建一个选择器
        private final static int port = 8686;
        private final static int BUF_SIZE = 10240;
        private void initServer() throws IOException{
            //创建通道管理器对象Selector
            this.selector = Selector.open();
            //创建一个通道对象channel
            ServerSocketChannel channel = ServerSocketChannel.open();
            //将通道设为非阻塞
            channel.configureBlocking(false);
            //将端口绑定在8686端口上
            channel.socket().bind(new InetSocketAddress(port));
            //将上述的通道管理器和通道绑定,并为该通道注册OP_ACCEPT事件
            //注册事件后,当该事件到达时,selector.select()会返回(一个key),如果该事件没有到达selector.select()会一直阻塞
            SelectionKey selectionKey = channel.register(selector, SelectionKey.OP_ACCEPT);
            while(true){//轮询
                //这是一个阻塞方法,一直等待直到有数据可读,返回值是key的数量(可以有多个)
                selector.select();
                //如果channel有数据了,将生成的key放入keys集合中
                Set keys = selector.selectedKeys();
                //得到这个keys的集合的迭代器
                Iterator iterator = keys.iterator();
                while(iterator.hasNext()){//使用迭代器遍历集合
                    //得到集合中的一个key的实例
                    SelectionKey key = (SelectionKey) iterator.next();
                    //拿到当前key实例之后记得在迭代器中将这个元素删除,否则会出错
                    iterator.remove();
                    if(key.isAcceptable()){//判断当前key所代表的channel是否在Acceptable状态,如果是就进行接受
                        doAccept(key);
                    }else if(key.isReadable()){
                        doRead(key);
                    }else if(key.isWritable() && key.isValid()){
                        doWrite(key);
                    }else if(key.isConnectable()){
                        System.out.println("连接成功");
                    }
                }
            }
        }
        
        public void doAccept(SelectionKey key) throws IOException{
            ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
            System.out.println("ServerSocketChannel正在监听");
            SocketChannel clientChannel = serverChannel.accept();
            clientChannel.configureBlocking(false);
            clientChannel.register(key.selector(),SelectionKey.OP_READ);
        }
        
        public void doRead(SelectionKey key) throws IOException{
            SocketChannel clientChannel = (SocketChannel) key.channel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIZE);
            long bytesRead = clientChannel.read(byteBuffer);
            while(bytesRead>0){
                byteBuffer.flip();
                byte[] data = byteBuffer.array();
                String info = new String(data);
                System.out.println("从客户端发送过来的消息是:"+info);
                byteBuffer.clear();
                bytesRead = clientChannel.read(byteBuffer);
            }
            if(bytesRead==-1){
                clientChannel.close();
            }
        }
        
        public void doWrite(SelectionKey key) throws IOException{
            ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIZE);
            byteBuffer.flip();
            SocketChannel clientChannel = (SocketChannel) key.channel();
            while(byteBuffer.hasRemaining()){
                clientChannel.write(byteBuffer);
            }
            byteBuffer.compact();
        }
        
        public static void main(String[] args) throws IOException{
            MyNioServer myNioServer = new MyNioServer();
            myNioServer.initServer();
        }
    }
    
    
    public class MyNioClient {
        private Selector selector;
        private final static int port = 8686;
        private final static int BUF_SIE = 10240;
        private static ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIE);
        
        private void initClient() throws IOException{
            this.selector = Selector.open();
            SocketChannel clientChannel = SocketChannel.open();
            clientChannel.configureBlocking(false);
            clientChannel.connect(new InetSocketAddress(port));
            clientChannel.register(selector, SelectionKey.OP_CONNECT);
            while(true){
                selector.select();
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while(iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if(key.isConnectable()){
                        doConnect(key);
                    }else if(key.isReadable()){
                        doRead(key);
                    }
                }
            }
        }
        
        public void doConnect(SelectionKey key) throws IOException{
            SocketChannel clientChannel = (SocketChannel) key.channel();
            if(clientChannel.isConnectionPending()){
                clientChannel.finishConnect();
            }
            clientChannel.configureBlocking(false);
            String info = "服务端,你好!!";
            byteBuffer.clear();
            byteBuffer.put(info.getBytes("UTF-8"));
            byteBuffer.flip();
            clientChannel.write(byteBuffer);
            clientChannel.close();
        }
        
        public void doRead(SelectionKey key) throws IOException{
            SocketChannel clientChannel = (SocketChannel) key.channel();
            clientChannel.read(byteBuffer);
            byte[] data = byteBuffer.array();
            String msg = new String(data).trim();
            System.out.println("服务端发送消息:"+msg);
            clientChannel.close();
            key.selector().close();
        }
        public static void main(String[] args) throws IOException {
            MyNioClient myNioClient = new MyNioClient();
            myNioClient.initClient();
        }
        
    }
    

    相关文章

      网友评论

          本文标题:NIO操作

          本文链接:https://www.haomeiwen.com/subject/rgcifqtx.html