1. 服务端
import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; import java.util.Set; public class NIOServer { public static void main(String[] args) throws Exception { // 1. 创建 ServerSocketChannel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 创建一个Selector对象 Selector selector = Selector.open(); // 绑定端口, 在服务端监听 serverSocketChannel.socket().bind(new InetSocketAddress(8888)); // 设置为非阻塞 serverSocketChannel.configureBlocking(false); // 将ServerSocketChannel注册到Selector上,关心事件为OP_ACCEPT serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 循环等待客户连接 while (true) { if (selector.select(1000) == 0) { // 服务器等待1秒,无连接 System.out.println("服务器等待1秒,无连接...."); continue; } // 有事件, 获取有事件发生的Channel的selectionKey Set<SelectionKey> selectedKeys = selector.selectedKeys(); // 通过selectionKey反向获取有事件的通道 Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { // 获取到selectionKey之后判断对应的通道发生事件的类型,然后做不同的处理 SelectionKey selectionKey = keyIterator.next(); if (selectionKey.isAcceptable()) {// 如果是连接事件,说明有新的客户端来连接 // 为该客户端创建 一个SocketChannel SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); System.out.println("客户端连接成功,生成一个socketChannel:" + socketChannel.hashCode()); // 将SocketChannel注册到Selector, 关注事件是OP_READ,同时给该SocketChannel关联一个Buffer socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } if (selectionKey.isReadable()) { // 读事件 SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); // 获取该Channel关联的buffer ByteBuffer buffer = (ByteBuffer) selectionKey.attachment(); // 将channel中的数据读取到buffer socketChannel.read(buffer); System.out.println("接收到客户端数据:" + new String(buffer.array())); } // 处理完之个selectionKey之后,从集合中删除, 否则会重复操作 keyIterator.remove(); } } } }
2. 客户端
import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class NIOClient { public static void main(String[] args) throws IOException { // 得到一个通道 SocketChannel socketChannel = SocketChannel.open(); // 设置非阻塞模式 socketChannel.configureBlocking(false); // 提供服务端的ip 和 端 SocketAddress address = new InetSocketAddress("127.0.0.1", 8888); // 连接服务端, 连接成功返回true,失败返回false boolean connectResult = socketChannel.connect(address); if (!connectResult) {// 连接不成功 while (!socketChannel.finishConnect()) {//如果连接还没有完成 System.out.println("因为连接需要时间,客户端不会阻塞。。。,可以干其它的事。。 "); } } // 如果连接成功,发送数据 String data = "hello world"; ByteBuffer buffer = ByteBuffer.wrap(data.getBytes()); // 发送数据,将buffer中数据写入channel socketChannel.write(buffer); // 不让程序关闭 System.in.read(); } }
日拱一卒无有尽,功不唐捐终入海