您的位置:首页 > 其它

NIO-实现聊天室

2022-04-16 17:52 239 查看

实现步骤:建立一个服务端和客户端

服务端

1、建立一个服务端

2、创建一个Selector选择器

3、创建一个Channel通道

4、绑定通道的监听端口

5、监听是否有新状态就去处理业务

public class TimServer {

public static void main(String[] args) throws IOException {
new TimServer().startServer();
}

public void startServer() throws IOException {
//创建选择器
Selector selector = Selector.open();
//创建通道
ServerSocketChannel ssc = ServerSocketChannel.open();
//为通道绑定端口
ssc.bind(new InetSocketAddress(8888));
//设置为非阻塞通道
ssc.configureBlocking(false);
//把通道注册到选择器 加上感兴趣的事件
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器启动成功!");
//循环监听
while (true) {
Set key = selector.selectedKeys();
Iterator<SelectionKey> iterable = key.iterator();
int readChannels = selector.select();
while (iterable.hasNext()) {
SelectionKey next = iterable.next();
//移除当前集合的key
iterable.remove();
if (next.isAcceptable()) {
accept(ssc,selector);

} else if (next.isReadable()) {
readable(selector,next);
}
}
}

}

/**
* 处理连接状态
* */
public  void accept(ServerSocketChannel serverSocketChannel,Selector selector) throws IOException {

//接入ServerSocketChannel
SocketChannel socketChannel = serverSocketChannel.accept();

//设置为非阻塞模式
socketChannel.configureBlocking(false);

//把channel注册到选择器上
socketChannel.register(selector,SelectionKey.OP_READ);

//回复信息
socketChannel.write(Charset.forName("UTF-8").encode("欢迎来到聊天室~"));
}

/**
* 处理可读状态
* */
public void readable(Selector selector,SelectionKey selectionKey) throws IOException {

//从SelectKey获取就绪的通道
SocketChannel socketChannel= (SocketChannel) selectionKey.channel();

//创建buffer
ByteBuffer buffer=ByteBuffer.allocate(1024);

//循环读取客户端信息
StringBuilder stringBuilder=new StringBuilder();
int readLength = socketChannel.read(buffer);
if (readLength>0){
//切换读模式
buffer.flip();
//读取内容
stringBuilder.append(Charset.forName("UTF-8").decode(buffer));
}
//把通道注册到选择器上
socketChannel.register(selector,SelectionKey.OP_READ);

//广播到其他客户端
if (stringBuilder.length()>0){
System.out.println(stringBuilder);
castClient(selector,socketChannel, String.valueOf(stringBuilder));
}
}

/**
* 广播到其他客户端
* */
public  void  castClient(Selector selector,SocketChannel socketChannel,String message) throws IOException {
// 获取所有已经接入的channel
Set<SelectionKey> selectionKeySet=selector.keys();

//循环所有广播消息
for (SelectionKey selectionKey : selectionKeySet) {
//获取每个channel
Channel tarChannel=selectionKey.channel();
//不需要给自己发送
if(tarChannel instanceof  SocketChannel&&tarChannel!=socketChannel){
((SocketChannel) tarChannel).write(Charset.forName("UTF-8").encode(message));
}
}

}
}

客户端

public class TimClient {
public static void main(String[] args) throws IOException {
new TimClient().startClient("ylc");
}

public void startClient(String name) throws IOException {
//连接服务器
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress( 8888));
//接收服务端响应
Selector selector = Selector.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);

//创建线程 获取服务器的消息
new Thread(new ClientThread(selector)).start();
//向服务器发送消息 控制台输入
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String msg = scanner.nextLine();
if (msg.length() > 0) {
socketChannel.write(Charset.forName("UTF-8").encode(name+":"+msg));
}
}
}

}

实现效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: