千家信息网

怎么使用Java NIO实现多人聊天室

发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,本篇内容主要讲解"怎么使用Java NIO实现多人聊天室",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么使用Java NIO实现多人聊天室"吧!NIO服
千家信息网最后更新 2025年11月09日怎么使用Java NIO实现多人聊天室

本篇内容主要讲解"怎么使用Java NIO实现多人聊天室",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么使用Java NIO实现多人聊天室"吧!

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 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 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;    }    @Override    public void run() {        try {            for (;;) {                int readyChannels = selector.select();                if (readyChannels == 0) continue;                /**                 * 获取可用channel的集合                 */                Set 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");    }}

到此,相信大家对"怎么使用Java NIO实现多人聊天室"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

客户 客户端 事件 服务 服务器 信息 处理 聊天室 UTF-8 接入 监听 内容 方法 模式 广播 循环 多人 处理器 消息 三个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网易大神服务器id 网络安全报道文章 山大网络安全研究所 怎么实现数据库每天备份 cas平台上的服务器启动不了 辽宁北斗卫星授时服务器云空间 竞技模式连接到官方服务器失败 泗阳小型网络技术哪家好 网络安全法学后心得体会 梦幻大唐官府服务器没上cbg 东港软件开发工资待遇 苹果软件开发工资多少 怎么看待嵌入式软件开发 下面的不是数据库技术特点 滴滴 软件开发 面试经验 绝世仙王轮回服务器苹果系统出错 2020研究生网络安全考试 数据库怎样转换为经济价值 从事软件开发大学生有培训班吗 小山日记软件开发 应该选什么软件开发 甘肃一对一软件开发 上海专业软件开发靠谱吗 竞技模式连接到官方服务器失败 长沙游戏软件开发收费 知网类似的数据库 我的世界服务器的漏洞 数据库的审计 雷雳网络安全教育与网络学习 数据库有几个类
0