NIO服务端

public class NioServer {/*** 启动*/public void start() throws IOException {/*** 1. 创建Selector*/Selector selector = Selector.open();/*** 2. 通过ServerSocketChannel创建channel通道*/ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();/*** 3. 为channel通道绑定监听端口*/serverSocketChannel.bind(new InetSocketAddress(8000));/*** 4. **设置channel为非阻塞模式***/serverSocketChannel.configureBlocking(false);/*** 5. 将channel注册到selector上,监听连接事件*/serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务器启动成功!");/*** 6. 循环等待新接入的连接*/for (;;) { // while(true) c for;;/*** TODO 获取可用channel数量*/int readyChannels = selector.select();/*** TODO 为什么要这样!!?*/if (readyChannels == 0) continue;/*** 获取可用channel的集合*/Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator iterator = selectionKeys.iterator();while (iterator.hasNext()) {/*** selectionKey实例*/SelectionKey selectionKey = (SelectionKey) iterator.next();/*** **移除Set中的当前selectionKey***/iterator.remove();/*** 7. 根据就绪状态,调用对应方法处理业务逻辑*//*** 如果是 接入事件*/if (selectionKey.isAcceptable()) {acceptHandler(serverSocketChannel, selector);}/*** 如果是 可读事件*/if (selectionKey.isReadable()) {readHandler(selectionKey, selector);}}}}/*** 接入事件处理器*/private void acceptHandler(ServerSocketChannel serverSocketChannel,Selector selector)throws IOException {/*** 如果要是接入事件,创建socketChannel*/SocketChannel socketChannel = serverSocketChannel.accept();/*** 将socketChannel设置为非阻塞工作模式*/socketChannel.configureBlocking(false);/*** 将channel注册到selector上,监听 可读事件*/socketChannel.register(selector, SelectionKey.OP_READ);/*** 回复客户端提示信息*/socketChannel.write(Charset.forName("UTF-8").encode("你与聊天室里其他人都不是朋友关系,请注意隐私安全"));}/*** 可读事件处理器*/private void readHandler(SelectionKey selectionKey, Selector selector)throws IOException {/*** 要从 selectionKey 中获取到已经就绪的channel*/SocketChannel socketChannel = (SocketChannel) selectionKey.channel();/*** 创建buffer*/ByteBuffer byteBuffer = ByteBuffer.allocate(1024);/*** 循环读取客户端请求信息*/String request = "";while (socketChannel.read(byteBuffer) > 0) {/*** 切换buffer为读模式*/byteBuffer.flip();/*** 读取buffer中的内容*/request += Charset.forName("UTF-8").decode(byteBuffer);}/*** 将channel再次注册到selector上,监听他的可读事件*/socketChannel.register(selector, SelectionKey.OP_READ);/*** 将客户端发送的请求信息 广播给其他客户端*/if (request.length() > 0) {// 广播给其他客户端broadCast(selector, socketChannel, request);}}/*** 广播给其他客户端*/private void broadCast(Selector selector,SocketChannel sourceChannel, String request) {/*** 获取到所有已接入的客户端channel*/Set<SelectionKey> selectionKeySet = selector.keys();/*** 循环向所有channel广播信息*/selectionKeySet.forEach(selectionKey -> {Channel targetChannel = selectionKey.channel();// 剔除发消息的客户端if (targetChannel instanceof SocketChannel&& targetChannel != sourceChannel) {try {// 将信息发送到targetChannel客户端((SocketChannel) targetChannel).write(Charset.forName("UTF-8").encode(request));} catch (IOException e) {e.printStackTrace();}}});}/*** 主方法* @param args*/public static void main(String[] args) throws IOException {new NioServer().start();}}

NIO客户端

public class NioClient {/*** 启动*/public void start(String nickname) throws IOException {/*** 连接服务器端*/SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8000));/*** 接收服务器端响应*/// 新开线程,专门负责来接收服务器端的响应数据// selector , socketChannel , 注册Selector selector = Selector.open();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);new Thread(new NioClientHandler(selector)).start();/*** 向服务器端发送数据*/Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String request = scanner.nextLine();if (request != null && request.length() > 0) {socketChannel.write(Charset.forName("UTF-8").encode(nickname + " : " + request));}}}public static void main(String[] args) throws IOException {//        new NioClient().start();}
}

客户端线程,处理服务器端响应的的消息

public class NioClientHandler implements Runnable {private Selector selector;public NioClientHandler(Selector selector) {this.selector = selector;}@Overridepublic void run() {try {for (;;) {int readyChannels = selector.select();if (readyChannels == 0) continue;/*** 获取可用channel的集合*/Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator iterator = selectionKeys.iterator();while (iterator.hasNext()) {/*** selectionKey实例*/SelectionKey selectionKey = (SelectionKey) iterator.next();/*** **移除Set中的当前selectionKey***/iterator.remove();/*** 7. 根据就绪状态,调用对应方法处理业务逻辑*//*** 如果是 可读事件*/if (selectionKey.isReadable()) {readHandler(selectionKey, selector);}}}} catch (IOException e) {e.printStackTrace();}}/*** 可读事件处理器*/private void readHandler(SelectionKey selectionKey, Selector selector)throws IOException {/*** 要从 selectionKey 中获取到已经就绪的channel*/SocketChannel socketChannel = (SocketChannel) selectionKey.channel();/*** 创建buffer*/ByteBuffer byteBuffer = ByteBuffer.allocate(1024);/*** 循环读取服务器端响应信息*/String response = "";while (socketChannel.read(byteBuffer) > 0) {/*** 切换buffer为读模式*/byteBuffer.flip();/*** 读取buffer中的内容*/response += Charset.forName("UTF-8").decode(byteBuffer);}/*** 将channel再次注册到selector上,监听他的可读事件*/socketChannel.register(selector, SelectionKey.OP_READ);/*** 将服务器端响应信息打印到本地*/if (response.length() > 0) {System.out.println(response);}}
}

我们定义三个客户端,模拟三个用户在聊天室发送消息

public class AClient {public static void main(String[] args)throws IOException {new NioClient().start("AClient");}
}public class BClient {public static void main(String[] args)throws IOException {new NioClient().start("BClient");}
}public class CClient {public static void main(String[] args)throws IOException {new NioClient().start("CClient");}}

NIO 聊天室到此结束

Java-NIO实战多人聊天室相关推荐

  1. Java NIO 实现多人聊天室

    服务端 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; impor ...

  2. java socket多人聊天室_如何运用Java socket实现多人聊天室功能

    如何运用Java socket实现多人聊天室功能 导语:如何运用Java socket实现多人聊天室功能呢?下面是小编给大家提供的代码实现,大家可以参考阅读,更多详情请关注应届毕业生考试网. 目录结构 ...

  3. java socket多人聊天_如何运用Java socket实现多人聊天室功能

    导语:如何运用Java socket实现多人聊天室功能呢?下面是小编给大家提供的代码实现,大家可以参考阅读,更多详情请关注应届毕业生考试网. 目录结构: ChatClient: package com ...

  4. java 多人聊天室_Java高效NIO之多人聊天室

    系统功能 使用NIO实现一个多人聊天室.聊天室包含以下功能. 服务端 处理客户连接 新连接客户端注册名字,并进行重名判断 新用户注册后向客户端广播用户列表 接收客户端消息并单播或广播 客户端 向服务端 ...

  5. Java TCP简易多人聊天室

    一.说明: ​ 本例是一个简易的Java TCP多人聊天室,先启动服务器端,再启动客户端,客户端敲入用户名,然后可以开始聊天,敲入信息,每一个在线的用户都会收到相应信息. 演示如下图: 二.服务器端代 ...

  6. Java网络编程——多人聊天室

    多用户即时通信系统 需求分析: 1.用户登录 2.拉取在线用户列表 3.无异常退出 4.私聊 5.群聊 6.发送文件 7.服务器推送新闻 多用户登录 老韩的课程讲的真的很清楚: 关于Java多线程的文 ...

  7. Java BIO多人聊天室

    基于上篇NIO的多人聊天室,这篇将用BIO也实现一遍 首先是服务端的设计: /*** @author Jing* @create 2020/5/17*/ public class ChatServer ...

  8. Java Socket实现简易多人聊天室传输聊天内容或文件

    Java Socket实现简易多人聊天室传输聊天内容或文件 Java小练手项目:用Java Socket实现多人聊天室,聊天室功能包括传输聊天内容或者文件.相比于其它的聊天室,增加了传输文件的功能供参 ...

  9. java仿qq聊天系统 多人聊天室

    目录 项目介绍 项目截图 服务器与客户端 新用户注册 注册新账号成功 进入聊天室 多人在线 选择发送文件 文件接收提醒 项目代码参考 服务器入口程序 服务器请求处理 原理解析 服务器多人网络连接: 如 ...

最新文章

  1. 让机器“看见”:图像数据的特征提取方法
  2. 2020年,你读到印象最深的论文是哪篇?
  3. 2007年3月东北微软技术活动预告
  4. linux 内核与用户空间通信之netlink使用方法
  5. JVM运行时栈帧结构
  6. 引用用户控件图片无法
  7. Eclipse中自定义注释
  8. 筛选染色体连续区域的策略
  9. pip报错Failed to establish a new connection: [Errno -3] Temporary failure in name resolution‘,)‘
  10. scala 高阶函数,闭包及柯里化
  11. MyEclipse中背景颜色的设定
  12. 【UVa10674】Tangents(两圆公切线的切点--验板子题)
  13. 推荐几个SQL在线学习网站
  14. 干货 | 每天十亿级数据更新,秒出查询结果,ClickHouse在携程酒店的应用
  15. jquery ztree 皮肤(官网介绍)
  16. 1357:车厢调度(train)
  17. Python——爬取喜马拉雅音频(抖音最火翻唱)
  18. 随机森林python实例_用Python实现随机森林算法的示例
  19. [0x7FFE1E17E050] ANOMALY: meaningless REX prefix used cmd窗口activate报错
  20. React中实现keepalive组件缓存效果

热门文章

  1. UVa - 1617 - Laptop
  2. 如何方便快速在指定文件夹打开命令行
  3. hibernate update sql
  4. 携号转网可能只会叫好不叫座
  5. Windows services相关命令
  6. 在Solaris 下使用Os Watcher 监控Oracle
  7. 新客户上云 –虚拟机及相关服务常见问题集锦
  8. 【Spring BootSpring Cloud系列】Spring Boot初识
  9. 命令行上的narrowing(随着输入逐步减少备选项)工具
  10. 轻量级HTTP服务器Nginx(Nginx性能优化技巧)