javaNIO的第一个例子

功能描述:一个服务器端,多个客户端,客户端向服务器端发送消息,服务器端转发给所有客户端(包括发送者)。

服务器端代码:

package com.imooc.nio; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; public class NioServer { public static void main(String[] args) throws Exception { /** * 开启一个服务端 * 设置为非阻塞 * 绑定端口号 */ ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.bind(new InetSocketAddress(8080)); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //UUID->客户端连接 Map clientMap = new HashMap<>(); while (true) { selector.select(); Set selectionKeys = selector.selectedKeys(); selectionKeys.forEach(selectionKey -> {try { if (selectionKey.isAcceptable()) { /** * 服务端接收到连接 * 保存接收到的客户端连接 */ ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = server.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector,SelectionKey.OP_READ); String key = UUID.randomUUID().toString(); clientMap.put(key,socketChannel); System.out.println(socketChannel.getRemoteAddress()+"连接上了服务器"); } else if (selectionKey.isReadable()) { /** * 读取客户端消息 * 转发到所有客户端 */ SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); try { ByteBuffer buffer = ByteBuffer.allocate(1024); int len = socketChannel.read(buffer); if (len > 0) { buffer.flip(); Charset charset = Charset.forName("UTF-8"); String receiveMsg = String.valueOf(charset.decode(buffer).array()); String key = null; for (Map.Entry entry : clientMap.entrySet()) { if (entry.getValue() == socketChannel) { key = entry.getKey(); break; } } String sendMsg = key + ":" + receiveMsg; System.out.println(sendMsg); for (Map.Entry entry : clientMap.entrySet()) { ByteBuffer writeBuffer = ByteBuffer.allocate(1024); writeBuffer.put(sendMsg.getBytes()); writeBuffer.flip(); entry.getValue().write(writeBuffer); } } }catch (Exception e) { e.printStackTrace(); //java.io.IOException: 远程主机强迫关闭了一个现有的连接。 socketChannel.close(); } } } catch (Exception e) { e.printStackTrace(); } }); selectionKeys.clear(); }} }

客户端代码:
package com.imooc.nio; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NioClient { public static void main(String[] args) throws Exception { /** * 开启一个客户端 * 设置为非阻塞 * 连接到服务器 */ SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress("localhost",8080)); Selector selector = Selector.open(); socketChannel.register(selector, SelectionKey.OP_CONNECT); while (true) { selector.select(); Set selectionKeys = selector.selectedKeys(); for (SelectionKey selectionKey : selectionKeys) { if (selectionKey.isConnectable()) { /** * 客户端已连接 * 开启一个线程监听控制台输入 */ SocketChannel client = (SocketChannel) selectionKey.channel(); if (client.isConnectionPending()) { client.finishConnect(); } client.register(selector,SelectionKey.OP_READ); ExecutorService executor = Executors.newSingleThreadExecutor(); System.out.println(socketChannel.getLocalAddress()+"连上了服务器"); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); executor.submit(()->{ try { while (true) { writeBuffer.clear(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String line = reader.readLine(); writeBuffer.put(line.getBytes()); writeBuffer.flip(); client.write(writeBuffer); } }catch (Exception e) { e.printStackTrace(); } }); } else if (selectionKey.isReadable()) { /** * 打印服务端消息 */ SocketChannel client = (SocketChannel) selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int len = client.read(readBuffer); System.out.println(new String(readBuffer.array(),0,len)); } } selectionKeys.clear(); } } }

【javaNIO的第一个例子】

    推荐阅读