1 importjava.io.IOException;2 importjava.net.InetSocketAddress;3 importjava.nio.ByteBuffer;4 import java.nio.channels.*;5 importjava.nio.charset.Charset;6 import java.util.*;7
8 /**
9 * @ClassName CharRoomServer10 * @Description TODO11 * @Author hufeng812 * @Date 2018/8/3 14:3913 * @Version 1.014 */
15 public class CharRoomServer implementsRunnable{16
17 private ServerSocketChannel serverSocketChannel = null;18
19 private Selector selector = null;20
21 public static final int PORT_NUM = 1198;22
23 private boolean active = true;24
25 private Charset charset = Charset.forName("UTF-8");26
27 private List users = new ArrayList();28
29 private ByteBuffer byteBuffer = ByteBuffer.allocate(2*1024);30
31 public static final String protocol = "#user#";32
33 publicCharRoomServer() {34 this.init();35 }36
37 public voidinit() {38 try{39 selector =Selector.open();40 serverSocketChannel =ServerSocketChannel.open();41 serverSocketChannel.socket().bind(newInetSocketAddress(PORT_NUM));42 serverSocketChannel.configureBlocking(false);43 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);44 } catch(IOException e) {45 e.printStackTrace();46 }47 }48
49 public voidrun() {50 System.out.println("开始监听。。。。");51 while(active) {52 try{53 //非阻塞接受连接54 //int s = selector.selectNow();55
56 //阻塞连接
57 int s =selector.select();58
59 System.out.println("服务端接受到连接总数"+selector.keys().size());60 } catch(IOException e) {61 e.printStackTrace();62 }63 System.out.println("服务端接受到的选择连接数"+selector.selectedKeys().size());64 Iterator keys =selector.selectedKeys().iterator();65 while(keys.hasNext()) {66 SelectionKey k =keys.next();67 keys.remove();68 //处理逻辑
69 doHandler(selector, k);70 }71 }72 }73
74 private voiddoHandler(Selector selector, SelectionKey k) {75 try{76 //连接事件
77 if(k.isConnectable()) {78 System.out.println("Connectable 连接事件");79 } else if(k.isAcceptable()) {80 ServerSocketChannel ser =(ServerSocketChannel) k.channel();81 if (ser ==serverSocketChannel) {82 System.out.println("同一个连接");83 }84 SocketChannel socketChannel =ser.accept();85 socketChannel.configureBlocking(false);86 socketChannel.register(selector, SelectionKey.OP_READ);87 socketChannel.write(charset.encode("please enter login name:"));88
89 //设置k为接受事件,准备接受其它请求?
90
91 } else if(k.isReadable()) {92 //获取客户端连接
93 SocketChannel socketChannel =(SocketChannel) k.channel();94 StringBuffer content = newStringBuffer();95 int sum = 0;96 try{97 byteBuffer.clear();98 while ((sum = socketChannel.read(byteBuffer)) > 0) {99 byteBuffer.flip();100 content.append(charset.decode(byteBuffer));101 }102 System.out.println(sum);103 //判断客户端连接关闭
104 if (sum == -1) {105 socketChannel.close();106 System.out.println("1--关闭连接");107 }108
109 System.out.println("服务端:监听:"+content.toString());110 } catch(Exception e) {111 System.out.println("2--关闭连接");112 k.cancel();113 if (null !=socketChannel) {114 socketChannel.close();115 }116 }117 if (content.length() > 0) {118 //按照协议切分内容
119 String[] contents =content.toString().split(protocol);120 //登陆用户
121 if (contents != null && contents.length == 1) {122 String user = contents[0];123 if(users.contains(user)) {124 socketChannel.write(charset.encode("登陆用户已存在!"));125 } else{126 users.add(user);127 //获取在线人数
128 int i =onlineCount(selector);129 //广播登陆消息给当前房间所有人
130 brokerMessage(selector, k, "欢迎"+user+"登陆,当前第"+i+"号");131 }132 } else if (contents != null && contents.length > 1) {133 String message = contents[0] + "say :" + contents[1];134 brokerMessage(selector, k, message);135 }136 }137 } else if(k.isWritable()) {138
139 }140 } catch(Exception e) {141 e.printStackTrace();142 }143 }144
145 /**
146 * 广播消息147 *@paramcontent148 */
149 private voidbrokerMessage(Selector selector, SelectionKey k, String content) {150 for(SelectionKey key : selector.keys()) {151 if (key.channel() instanceof SocketChannel && key !=k) {152 try{153 SocketChannel sc =(SocketChannel) key.channel();154 sc.write(charset.encode(content));155 } catch(IOException e1) {156 e1.printStackTrace();157 }158 }159 }160 }161
162 /**
163 * 统计在线人数164 *@paramselector165 *@return
166 */
167 private intonlineCount(Selector selector) {168
169 return 0;170 }171
172 public static voidmain(String[] args) {173 System.out.println("开始启动服务");174 new Thread(newCharRoomServer()).start();175 System.out.println("服务启动");176 }177 }