实现步骤:建立一个服务端和客户端
服务端
1、建立一个服务端
2、创建一个Selector选择器
3、创建一个Channel通道
4、绑定通道的监听端口
5、监听是否有新状态就去处理业务
public class TimServer { public static void main(String[] args) throws IOException { new TimServer().startServer(); } public void startServer() throws IOException { //创建选择器 Selector selector = Selector.open(); //创建通道 ServerSocketChannel ssc = ServerSocketChannel.open(); //为通道绑定端口 ssc.bind(new InetSocketAddress(8888)); //设置为非阻塞通道 ssc.configureBlocking(false); //把通道注册到选择器 加上感兴趣的事件 ssc.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务器启动成功!"); //循环监听 while (true) { Set key = selector.selectedKeys(); Iterator<SelectionKey> iterable = key.iterator(); int readChannels = selector.select(); while (iterable.hasNext()) { SelectionKey next = iterable.next(); //移除当前集合的key iterable.remove(); if (next.isAcceptable()) { accept(ssc,selector); } else if (next.isReadable()) { readable(selector,next); } } } } /** * 处理连接状态 * */ public void accept(ServerSocketChannel serverSocketChannel,Selector selector) throws IOException { //接入ServerSocketChannel SocketChannel socketChannel = serverSocketChannel.accept(); //设置为非阻塞模式 socketChannel.configureBlocking(false); //把channel注册到选择器上 socketChannel.register(selector,SelectionKey.OP_READ); //回复信息 socketChannel.write(Charset.forName("UTF-8").encode("欢迎来到聊天室~")); } /** * 处理可读状态 * */ public void readable(Selector selector,SelectionKey selectionKey) throws IOException { //从SelectKey获取就绪的通道 SocketChannel socketChannel= (SocketChannel) selectionKey.channel(); //创建buffer ByteBuffer buffer=ByteBuffer.allocate(1024); //循环读取客户端信息 StringBuilder stringBuilder=new StringBuilder(); int readLength = socketChannel.read(buffer); if (readLength>0){ //切换读模式 buffer.flip(); //读取内容 stringBuilder.append(Charset.forName("UTF-8").decode(buffer)); } //把通道注册到选择器上 socketChannel.register(selector,SelectionKey.OP_READ); //广播到其他客户端 if (stringBuilder.length()>0){ System.out.println(stringBuilder); castClient(selector,socketChannel, String.valueOf(stringBuilder)); } } /** * 广播到其他客户端 * */ public void castClient(Selector selector,SocketChannel socketChannel,String message) throws IOException { // 获取所有已经接入的channel Set<SelectionKey> selectionKeySet=selector.keys(); //循环所有广播消息 for (SelectionKey selectionKey : selectionKeySet) { //获取每个channel Channel tarChannel=selectionKey.channel(); //不需要给自己发送 if(tarChannel instanceof SocketChannel&&tarChannel!=socketChannel){ ((SocketChannel) tarChannel).write(Charset.forName("UTF-8").encode(message)); } } } }
客户端
public class TimClient { public static void main(String[] args) throws IOException { new TimClient().startClient("ylc"); } public void startClient(String name) throws IOException { //连接服务器 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress( 8888)); //接收服务端响应 Selector selector = Selector.open(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); //创建线程 获取服务器的消息 new Thread(new ClientThread(selector)).start(); //向服务器发送消息 控制台输入 Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String msg = scanner.nextLine(); if (msg.length() > 0) { socketChannel.write(Charset.forName("UTF-8").encode(name+":"+msg)); } } } }
实现效果: