基于NIO实现后台简易群聊系统
Posted hyy9527
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于NIO实现后台简易群聊系统相关的知识,希望对你有一定的参考价值。
1.服务端
public class GroupChatServer { private Selector selector; private ServerSocketChannel listenChannel; private static final int PORT = 6677; //初始化工作 public GroupChatServer() { try { selector = Selector.open(); listenChannel = ServerSocketChannel.open(); //绑定端口 listenChannel.socket().bind(new InetSocketAddress(PORT)); //设置非阻塞 listenChannel.configureBlocking(false); //注册 listenChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (Exception e) { e.printStackTrace(); } } //监听 public void listen() { try { while (true) { int count = selector.select(2000); if (count > 0) { //遍历得到SelectionKey的集合 Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); //获取key SelectionKey key = iterator.next(); //监听accept if (key.isAcceptable()) { SocketChannel socketChannel = listenChannel.accept(); socketChannel.configureBlocking(false); //将socketChannel注册到selector socketChannel.register(selector, SelectionKey.OP_READ); //提示上线 System.out.println(socketChannel.getRemoteAddress().toString().substring(1) + "上线了"); } if (key.isReadable()) {//通道为可读状态 //读取数据 readData(key); } //删除当前key,防止重复处理 iterator.remove(); } } } catch (Exception ex) { ex.printStackTrace(); } } //读取客户发送的消息 public void readData(SelectionKey key) { //定义一个SocketChannel SocketChannel channel = null; try { //得到channel channel = (SocketChannel) key.channel(); //创建buffer ByteBuffer byteBuffer = ByteBuffer.allocate(1024); int read = channel.read(byteBuffer); if (read > 0) { //缓存区的数据转存到字符串 String msg = new String(byteBuffer.array()); //输出 System.out.println("来自客户端的消息" + msg); //服务器接收到某个客户的消息后,转发给其他客户 sendToOthers(msg, channel); } } catch (IOException e) {//此时表示客户离线了 try { System.out.println(channel.getRemoteAddress() + "离线了...."); //取消注册 key.cancel(); //关闭通道 channel.close(); } catch (IOException e1) { e1.printStackTrace(); } e.printStackTrace(); } } //消息转发给其他用户 private void sendToOthers(String msg, SocketChannel self) throws IOException { System.out.println("服务器消息转发中..."); //遍历已经注册到selector的socketchannel,排除自己在外 for (SelectionKey key : selector.keys()) { //通过key取出对应的socketChannel Channel channel = key.channel(); //排除自己的channel if (channel instanceof SocketChannel & channel != self) { //转型 SocketChannel dest = (SocketChannel) channel; //将msg转存到buffer ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes()); //将buffer数据写入到通道 dest.write(byteBuffer); } } } //服务器启动 public static void main(String[] args) { GroupChatServer groupChatServer = new GroupChatServer(); groupChatServer.listen(); } }
2.客户端
public class GroupChatClient { private SocketChannel socketChannel = null; private Selector selector = null; private final static int PORT = 6677; private final static String HOST = "127.0.0.1"; private String userName; //初始化 public GroupChatClient() throws IOException { selector = Selector.open(); //链接服务器 socketChannel = SocketChannel.open(new InetSocketAddress(HOST, PORT)); //设置非阻塞 socketChannel.configureBlocking(false); //注册 socketChannel.register(selector, SelectionKey.OP_READ); //获取用户名 userName = socketChannel.getLocalAddress().toString().substring(1); System.out.println(userName + " is ok...."); } //向服务器发送消息 public void sendInfo(String info) { info = userName + "说:" + info; try { socketChannel.write(ByteBuffer.wrap(info.getBytes())); } catch (IOException e) { e.printStackTrace(); } } //从服务器端回复消息 public void readInfo() { try { int select = selector.select(); if (select > 0) {//判断是否有可用的通道 //获取key集合 Set<SelectionKey> selectionKeys = selector.selectedKeys(); //迭代 Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); if (key.isReadable()) { //得到相关通道 SocketChannel channel = (SocketChannel) key.channel(); //得到一个buffer ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //读取 channel.read(byteBuffer); //数据转为字符串 String s = new String(byteBuffer.array()); System.out.println(s.trim()); } } iterator.remove(); } else { } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { GroupChatClient chatClient = new GroupChatClient(); //读取数据 new Thread() { public void run() { while (true) { chatClient.readInfo(); } } }.start(); //发送数据 Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { String s = sc.nextLine(); chatClient.sendInfo(s); } } }
public class GroupChatServer {
private Selector selector;
private ServerSocketChannel listenChannel;
private static final int PORT = 6677;
//初始化工作
public GroupChatServer() {
try {
selector = Selector.open();
listenChannel = ServerSocketChannel.open();
//绑定端口
listenChannel.socket().bind(new InetSocketAddress(PORT));
//设置非阻塞
listenChannel.configureBlocking(false);
//注册
listenChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
e.printStackTrace();
}
}
//监听
public void listen() {
try {
while (true) {
int count = selector.select(2000);
if (count > 0) {
//遍历得到SelectionKey的集合
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
//获取key
SelectionKey key = iterator.next();
//监听accept
if (key.isAcceptable()) {
SocketChannel socketChannel = listenChannel.accept();
socketChannel.configureBlocking(false);
//将socketChannel注册到selector
socketChannel.register(selector, SelectionKey.OP_READ);
//提示上线
System.out.println(socketChannel.getRemoteAddress().toString().substring(1) + "上线了");
}
if (key.isReadable()) {//通道为可读状态
//读取数据
readData(key);
}
//删除当前key,防止重复处理
iterator.remove();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
//读取客户发送的消息
public void readData(SelectionKey key) {
//定义一个SocketChannel
SocketChannel channel = null;
try {
//得到channel
channel = (SocketChannel) key.channel();
//创建buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int read = channel.read(byteBuffer);
if (read > 0) {
//缓存区的数据转存到字符串
String msg = new String(byteBuffer.array());
//输出
System.out.println("来自客户端的消息" + msg);
//服务器接收到某个客户的消息后,转发给其他客户
sendToOthers(msg, channel);
}
} catch (IOException e) {//此时表示客户离线了
try {
System.out.println(channel.getRemoteAddress() + "离线了....");
//取消注册
key.cancel();
//关闭通道
channel.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
//消息转发给其他用户
private void sendToOthers(String msg, SocketChannel self) throws IOException {
System.out.println("服务器消息转发中...");
//遍历已经注册到selector的socketchannel,排除自己在外
for (SelectionKey key : selector.keys()) {
//通过key取出对应的socketChannel
Channel channel = key.channel();
//排除自己的channel
if (channel instanceof SocketChannel & channel != self) {
//转型
SocketChannel dest = (SocketChannel) channel;
//将msg转存到buffer
ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
//将buffer数据写入到通道
dest.write(byteBuffer);
}
}
}
//服务器启动
public static void main(String[] args) {
GroupChatServer groupChatServer = new GroupChatServer();
groupChatServer.listen();
}
}
以上是关于基于NIO实现后台简易群聊系统的主要内容,如果未能解决你的问题,请参考以下文章