> 文档中心 > 入门:初探NIO原理及使用

入门:初探NIO原理及使用

//Socket服务器端public class NIOServer03 {    public static void main(String[] args) throws IOException { //创建选择器(多路复用器)对象 Selector selector = Selector.open(); //创建Socket服务端通道对象 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //配置为非阻塞 serverSocketChannel.configureBlocking(false); //将Socket服务端通道的对象注册到选择器上,并指定其通道对象的注册事件为接收事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //指定Socket服务端的IP地址和端口 InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888); //绑定地址 serverSocketChannel.bind(address); //服务端需要一直建立连接保存与客户端通讯,所以这里设为死循环 while(true){     //开启选择器进行监听,这里至少选择一个通道,如果该选择器是关闭抛出ClosedSelectorException     selector.select();     //返回此选择器的选定键集(注册的事件)。如果该选择器是关闭抛出ClosedSelectorException     Set<SelectionKey> selectionKeys = selector.selectedKeys();     //用迭代器遍历选定键集     Iterator<SelectionKey> keyIterator = selectionKeys.iterator();     while (keyIterator.hasNext()) {  SelectionKey key = keyIterator.next();  //如果key的注册事件为接收事件时执行  if(key.isAcceptable()){      //返回为其创建此密钥(key)的通道      ServerSocketChannel socketChannelByKey = (ServerSocketChannel) key.channel();      /*** 接收与此通道的套接字建立的连接* 如果没有挂起的连接,会立即返回null,否则它将无限期阻塞,直到有新连接或发生I/O错误* 返回新连接的套接字通道*/      SocketChannel socketChannel = socketChannelByKey.accept();      //设为非阻塞      socketChannel.configureBlocking(false);      //将该套接字通道注册为读取事件      socketChannel.register(selector, SelectionKey.OP_READ);  }else if(key.isReadable()){ //如果key的注册事件为读取事件时执行      //返回为其创建此密钥(key)的通道      SocketChannel socketChannel = (SocketChannel) key.channel();      //解析读取该通道上的数据并返回打印      String data = readDataFromSocketChannel(socketChannel);      System.out.println("return data:"+data);      //关闭该套接字通道      socketChannel.close();  }  //没有其他注册事件则移除该key键  keyIterator.remove();     } }    }    private static String readDataFromSocketChannel(SocketChannel socketChannel) throws IOException { StringBuilder data=new StringBuilder(); //分配一个新的字节缓冲区,新缓冲区的位置将为零,它的限制将是它的容量,即1024(B),如果容量为负整数则抛出IllegalArgumentException ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while(true){    //循环读取数据     //清空缓冲区     //byteBuffer.clear();     //将Socket通道中数据读入字节缓冲区中     int read = socketChannel.read(byteBuffer);     if(read == -1){  //缓冲区不存在数据时停止循环  break;     }     //翻转这个缓冲区.限制设置为当前位置     byteBuffer.flip();     //返回此缓冲区的限制     int limit = byteBuffer.limit();     //设置字符数组,存储读取的数据     char[] dst=new char[limit];     for (int i = 0; i < limit; i++) {  //获取读取的数据  dst[i]= (char) byteBuffer.get(i);     }     //存入StringBuilder对象中     data.append(dst);     //byteBuffer.clear(); } return data.toString();    }}
//Socket客户端public class NIOClient03 {    public static void main(String[] args) throws IOException { //根据IP地址与端口与Socket服务器建立连接 Socket socket=new Socket("127.0.0.1",8888); //获取socket中输出流并写入 OutputStream outputStream = socket.getOutputStream(); outputStream.write("hello world".getBytes()); //关闭输出流 outputStream.close();    }}

执行结果:
在这里插入图片描述

Python学习手册