package com.rlovep.talk; import java.io.IOException; 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.util.HashMap; import java.util.Iterator; import java.util.Map; public class TalkServer { //通道选择器 private Selector selector; private Map<String, SocketChannel> map=new HashMap<>(); //常量定义: private static final String login="login"; private static final String single="single"; /** * * @Title: initServer * @Description:服务端初始化,获得serverSocker通道 注册到通道选择器 * @author peace w_peace12@163.com */ public void initServer(int port) throws IOException{ //获得一个ServerSocket通道 ServerSocketChannel server = ServerSocketChannel.open(); //设置为通道非组塞 server.configureBlocking(false); //将服务器监听port端口 server.socket().bind(new InetSocketAddress(port)); //获得通道选择器 this.selector=Selector.open(); //将服务通道绑定到通道选择器,并为该通道注册SelectionKey.OP_ACCEPT事件,当accept事件到达时,selector.select()会返回事件 server.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务端初始化成功"); } /** * * @Title: AllServer * @Description: 采用循环访问select上是否有需要处理时间,如果有则进行处理, * 包括:server端accept和建立连接客户端的socket通道 * @author peace w_peace12@163.com */ public void AllServer()throws IOException{ while(true){ //阻塞调用线程,直到有某个Channel的某个感兴趣的事件准备好了 int i=selector.select(); if(i==0)continue; //获得selector中存在的事件 Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while(iterator.hasNext()) { //获得该键值 SelectionKey key=iterator.next(); //accept if(key.isAcceptable()){ //获得产生事件的通道 ServerSocketChannel server = (ServerSocketChannel)key.channel(); //获得和客户端连接的通道 SocketChannel channel = server.accept(); //设置成非阻塞 channel.configureBlocking(false); //向客户端发送一条连接成功消息 channel.write(ByteBuffer.wrap(new String("连接成功").getBytes())); //将客户端连接通道绑定到选择器,并注册read事件 channel.register(selector, SelectionKey.OP_READ); } //获得read事件 if(key.isReadable()) { //获得客户端连接通道 SocketChannel channel = (SocketChannel)key.channel(); //创建缓存区 ByteBuffer buffer=ByteBuffer.allocate(128); //获得消息 channel.read(buffer); //去掉头尾空字符 String msg=new String(buffer.array()).trim(); String[] mStrings=msg.split("_"); //显示消息 System.out.println("服务器接收到消息为:"+msg); switch (mStrings[0]) { case login: map.put(mStrings[1], channel); //将消息发送回去 channel.write(ByteBuffer.wrap(new String("登陆成功").getBytes())); break; case single: SocketChannel channel2 = map.get(mStrings[1]); channel2.write(ByteBuffer.wrap(mStrings[2].getBytes())); break; default: break; } } //删除已处理事件 iterator.remove(); } } } /** * 启动服务端程序: */ public static void main(String[] args) { try { TalkServer servier=new TalkServer(); servier.initServer(6666); servier.AllServer(); } catch (IOException e) { System.out.println("错误"); } } }