服务端:
//先新建ServerSocketChannel来监听端口 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //设置为非阻塞 serverSocketChannel.configureBlocking(false); //新建一个Selector Selector selector = Selector.open(); //开始监听端口 InetSocketAddress inetSocketAddress = new InetSocketAddress(6666); //监听端口 serverSocketChannel.socket().bind(inetSocketAddress); //然后把ServerSocketChannel注册到selector中,并关心事件为accept serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //开始进行监听后的操作,轮询等待客户端 while(true){ //判断是否有正在发生事件的通道 if (selector.select(1000)==0){ System.out.println("服务等待了一秒钟,无连接"); continue; } //如果返回的是大于0 ,则获取相关的selectionKey集合 Set<SelectionKey> selectionKeys = selector.selectedKeys(); //对这些key遍历进行业务操作 selectionKeys.stream().forEach(selectionKey -> { //如果改key是注册的意思,就先对其进行注册 if (selectionKey.isAcceptable()){ try { //创建一个socketchannel为客户端所用 SocketChannel socketChannel = serverSocketChannel.accept(); System.out.println("有客户端进行连接:"+socketChannel.hashCode()); socketChannel.configureBlocking(false); //需要把socketchannel也注册到selector上 socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } catch (IOException e) { e.printStackTrace(); } }if (selectionKey.isReadable()){ //如果是可读的事件,则对其进行读取 try { //通过selectionKey来得到channel SocketChannel channel = (SocketChannel)selectionKey.channel(); //通过selectionKey来得到buffer ByteBuffer attachment = (ByteBuffer)selectionKey.attachment(); //将buffer的数据读到channel channel.read(attachment); System.out.println("from 客户端"+new String(attachment.array())); } catch (IOException e) { e.printStackTrace(); } } }); } }
客户端:
//新建一个客户端使用的socketchannel SocketChannel socketChannel = SocketChannel.open(); //设置为非阻塞channel socketChannel.configureBlocking(false); //连接上服务端的6666端口 InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 6666); //开始连接 boolean connect = socketChannel.connect(socketAddress); if (!connect){ //没连接上,然后判断连接是否已经中断,如果还没有中断,则提示 while (!socketChannel.finishConnect()){ System.out.println("连接还未中断,可以进行其他操作"); } }else { //连接成功,开始发送信息 String str="客户端发送信息为1"; //这里ByteBuffer提供了一个方法,避免了资源浪费,以往是使用allocal方法来开启一个有大小的buffer //这里的wrap方法是可以根据byte数组的大小来定义buffer的大小的,这样不会造成资源浪费 ByteBuffer byteBuffer = ByteBuffer.wrap(str.getBytes()); //nio里面的传输数据,就是把buffer里面的数据,写入到channel就行了 socketChannel.write(byteBuffer); System.in.read(); }