public class Server {
//backlog为accept队列大小,默认值为50
private static final int BACKLOG = 1024;
private static final String IP = "127.0.0.1";
private static final int PORT = 8888;
private ServerSocketChannel serverChannel;
private Selector selector;
//构造函数
public Server() {
try {
//打开服务端通道
serverChannel = ServerSocketChannel.open();
//设置非阻塞
serverChannel.configureBlocking(false);
//绑定端口,在服务端监听
serverChannel.bind(new InetSocketAddress(IP, PORT), BACKLOG);
//打开选择器
selector = Selector.open();
//把服务端通道注册到选择器,关注的事件是接收
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
//监听客户端
public void listen() {
try {
//循环等待客户端连接
for (; ; ) {
int readChannel = selector.select();
// if (selector.select(1000) == 0) {
// System.out.println("无连接,服务器等待...");
// continue;
// }
if (readChannel > 0) {
//关注事件集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
//如果是OP_ACCEPT,有新的客户端连接
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
//关联buffer
//channel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
//把通道注册到选择器,关注的事件是读
channel.register(selector, SelectionKey.OP_READ);
System.out.println(channel.getRemoteAddress() + "上线了...");
}
if (key.isReadable()) {
readClient(key);
}
//移除Selection,因为多线程,要防止重复操作
iterator.remove();
}
} else {
System.out.println("没有可用通道!");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
//读取客户端
private void readClient(SelectionKey key) {
SocketChannel channel = null;
try {
channel = (SocketChannel) key.channel();
//获取buffer
//ByteBuffer buffer = (ByteBuffer) key.attachment();
//ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());
ByteBuffer buffer = ByteBuffer.allocate(1024);
//把通道数据放入缓冲区
int count = channel.read(buffer);
if (count > 0) {
String msg = new String(buffer.array());
System.out.println("客户端:" + msg);
//转发到其他客户端
sendClient(msg, channel);
}
} catch (IOException e) {
try {
System.out.println(channel.getRemoteAddress() + "离线了...");
//取消注册
key.cancel();
//关闭通道
channel.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
}
}
//转发给其他客户端,也就是给通道发(排除自己)
private void sendClient(String msg, SocketChannel self) throws IOException {
//遍历所有注册到选择器的通道,并排除自己
for (SelectionKey key : selector.keys()) {
Channel targetChannel = key.channel();
//排除自己
if (targetChannel instanceof SocketChannel && targetChannel != self) {
//转型
SocketChannel dest = (SocketChannel) targetChannel;
ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
//把缓冲区数据放入通道
dest.write(buffer);
}
}
}
public static void main(String[] args) throws Exception {
Server server = new Server();
server.listen();
}
}