packagecom.leam.springboot.nio;importjava.io.IOException;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.ServerSocketChannel;importjava.nio.channels.SocketChannel;importjava.nio.charset.Charset;importjava.util.HashMap;importjava.util.Map;importjava.util.Set;importjava.util.UUID;/*** NIO服务端转发个所有客户端*/
public classNioServer {private staticSelector selector;/*** 开启一个服务端
* 设置为非阻塞
* 绑定端口号
* backlog 处理的最大连接数,大于这个数直接拒绝*/
static{try{
ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(9999));
selector=Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}catch(IOException e) {
e.printStackTrace();
}
}public static void server() throwsIOException {
Map clientMap = new HashMap<>(0);while (true) {
selector.select();
Set selectionKeys =selector.selectedKeys();
selectionKeys.forEach(selectionKey->{try{if(selectionKey.isAcceptable()) {/*** 服务器接收到客户端链接
* 保存接收到的客户端链接*/ServerSocketChannel server=(ServerSocketChannel) selectionKey.channel();
SocketChannel channel=server.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
String key=UUID.randomUUID().toString();
clientMap.put(key, channel);
System.out.println(channel.getRemoteAddress()+ "链接上服务器");
}else if(selectionKey.isReadable()) {/*** 读取客户端消息
* 转发到所有客户端*/
try{
SocketChannel channel=(SocketChannel) selectionKey.channel();
ByteBuffer buffer= ByteBuffer.allocate(1024);int len =channel.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.Entryentry : clientMap.entrySet()) {if (entry.getValue() ==channel) {
key=entry.getKey();break;
}
}
String sendMsg= key + ":" +receiveMsg;
System.out.println(sendMsg);for (Map.Entryentry : clientMap.entrySet()) {
ByteBuffer writeBuffer= ByteBuffer.allocate(1024);
writeBuffer.put(charset.encode(sendMsg));
writeBuffer.flip();
entry.getValue().write(writeBuffer);
}
}
}catch(Exception e) {
e.printStackTrace();
System.out.println("远程主机强迫关闭了一个现有的连接11111");
}
}
}catch(Exception e) {
System.out.println("服务端出来异常");
}
});
selectionKeys.clear();
}
}public static void main(String args[]) throwsIOException {
server();
}
}