千家信息网

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

发表于:2024-09-23 作者:千家信息网编辑
千家信息网最后更新 2024年09月23日,本篇内容主要讲解"怎么使用Java NIO实现多人聊天室",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么使用Java NIO实现多人聊天室"吧!NIO服
千家信息网最后更新 2024年09月23日怎么使用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安全错误 数据库的锁怎样保障安全 网络安全法要求应当要求用户提供 学校网络安全教育宣传片 上海软件开发者哪家好 昆明电视教育台网络安全知识讲 富士通服务器 浙江5g服务器小型机柜虚拟主机 新点电子询标系统服务器地址 数据库首字母大写的函数 电力网络安全区域 测试服务器端口是否打开 推广软件软件开发 安徽软件开发者公司 计算机网络安全毕业论文英文 怎么在电脑上搞一个服务器 渝北区提供软件开发服务公司 建立数据库的好处酒店 服务器管理器文档选项卡在哪 英文对于软件开发人员来说 IBM服务器P系列 来凤县服务器租赁 手机没有欠费显示无法连接服务器 数据库启用远程登录 网络安全专业的大咖 与服务器通讯时出现了错误 软件开发工程师证书报考入口 无人值守停车软件开发 广州番禺销售软件开发 查看服务器内存型号 上海医院数显钟服务器 顾客满意度调查软件开发
0