千家信息网

Java基于NIO如何实现群聊系统

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要为大家展示了"Java基于NIO如何实现群聊系统",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Java基于NIO如何实现群聊系统"这篇文章吧。
千家信息网最后更新 2026年10月31日Java基于NIO如何实现群聊系统

这篇文章主要为大家展示了"Java基于NIO如何实现群聊系统",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Java基于NIO如何实现群聊系统"这篇文章吧。

具体内容如下

实例要求:

1.编写一个 NIO 群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞)

2.实现多人群聊

3.服务器端:可以监测用户上线,离线,并实现消息转发功能

4.客户端:通过 Channel 可以无阻塞发送消息给其它所有用户,同时可以接受其它用户发送的消息(有服务器转发得到)

5.目的:进一步理解 NIO 非阻塞网络编程机制

6.示意图分析和代码

// 服务端:

package com.atguigu.nio.groupchat;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.Channel;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;public class GroupChatServer {    //定义属性    private Selector selector;    private ServerSocketChannel listenChannel;    private static final int PORT = 6667;    //构造器    //初始化工作    public GroupChatServer() {        try {            //得到选择器            selector = Selector.open();            //ServerSocketChannel            listenChannel = ServerSocketChannel.open();            //绑定端口            listenChannel.socket().bind(new InetSocketAddress(PORT));            //设置非阻塞模式            listenChannel.configureBlocking(false);            //将该 listenChannel 注册到 selector            listenChannel.register(selector, SelectionKey.OP_ACCEPT);        } catch (IOException e) {            e.printStackTrace();        }    }    public void listen() {        try {            //循环处理            while (true) {                int count = selector.select();                if (count > 0) { //有事件处理                    // 遍历得到 selectionKey 集合                    Iterator iterator = selector.selectedKeys().iterator();                    while (iterator.hasNext()) {                        //取出 selectionkey                        SelectionKey key = iterator.next();                        //监听到 accept                        if (key.isAcceptable()) {                            SocketChannel sc = listenChannel.accept();                            sc.configureBlocking(false);                            //将该 sc 注册到 seletor                            sc.register(selector, SelectionKey.OP_READ);                            //提示                            System.out.println(sc.getRemoteAddress() + " 上线 ");                        }                        if (key.isReadable()) {//通道发送read事件,即通道是可读的状态                            // 处理读(专门写方法..)                            readData(key);                        }                        //当前的 key 删除,防止重复处理                        iterator.remove();                    }                } else {                    System.out.println("等待....");                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            //发生异常处理....        }    }    //读取客户端消息    public void readData(SelectionKey key) {        SocketChannel channel = null;        try {            //得到 channel            channel = (SocketChannel) key.channel();            //创建 buffer            ByteBuffer buffer = ByteBuffer.allocate(1024);            int count = channel.read(buffer);            //根据 count 的值做处理            if (count > 0) {                //把缓存区的数据转成字符串                String msg = new String(buffer.array());                //输出该消息                System.out.println("form客户端:" + msg);                //向其它的客户端转发消息(去掉自己),专门写一个方法来处理                sendInfoToOtherClients(msg, channel);            }        } catch (IOException e) {            try {                System.out.println(channel.getRemoteAddress() + "离线了..");                //取消注册                key.cancel();                //关闭通道                channel.close();            } catch (IOException e2) {                e2.printStackTrace();            }        }    }    //转发消息给其它客户(通道)    private void sendInfoToOtherClients(String msg, SocketChannel self) throws IOException {        System.out.println("服务器转发消息中...");        //遍历所有注册到 selector 上的 SocketChannel,并排除 self        for (SelectionKey key : selector.keys()) {            //通过 key 取出对应的 SocketChannel            Channel targetChannel = key.channel();            //排除自己            if (targetChannel instanceof SocketChannel && targetChannel != self) {                //转型                SocketChannel dest = (SocketChannel) targetChannel;                //将 msg 存储到 buffer                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());                //将 buffer 的数据写入通道                dest.write(buffer);            }        }    }    public static void main(String[] args) {        //创建服务器对象        GroupChatServer groupChatServer = new GroupChatServer();        groupChatServer.listen();    }}

// 客户端:

package com.atguigu.nio.groupchat;~~import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Scanner;public class GroupChatClient {    //定义相关的属性    private final String HOST = "127.0.0.1";//服务器的ip    private final int PORT = 6667;//服务器端口    private Selector selector;    private SocketChannel socketChannel;    private String username;    //构造器,完成初始化工作    public GroupChatClient() throws IOException {                selector = Selector.open();        //连接服务器        socketChannel = SocketChannel.open(new InetSocketAddress(HOST, PORT));        //设置非阻塞        socketChannel.configureBlocking(false);        //将 channel 注册到selector        socketChannel.register(selector, SelectionKey.OP_READ);        //得到 username        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 readChannels = selector.select();            if (readChannels > 0) {//有可以用的通道                Iterator iterator = selector.selectedKeys().iterator();                while (iterator.hasNext()) {                    SelectionKey key = iterator.next();                    if (key.isReadable()) {                        //得到相关的通道                        SocketChannel sc = (SocketChannel) key.channel();                        //得到一个 Buffer                        ByteBuffer buffer = ByteBuffer.allocate(1024);                        //读取                        sc.read(buffer);                        //把读到的缓冲区的数据转成字符串                        String msg = new String(buffer.array());                        System.out.println(msg.trim());                    }                }                iterator.remove(); //删除当前的 selectionKey,防止重复操作            } else {                //System.out.println("没有可以用的通道...");            }        } catch (Exception e) {            e.printStackTrace();        }    }    public static void main(String[] args) throws Exception {        //启动我们客户端        GroupChatClient chatClient = new GroupChatClient();        //启动一个线程,每个 3 秒,读取从服务器发送数据        new Thread() {            public void run() {                while (true) {                    chatClient.readInfo();                    try {                        Thread.currentThread().sleep(3000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }.start();        //发送数据给服务器端        Scanner scanner = new Scanner(System.in);        while (scanner.hasNextLine()) {            String s = scanner.nextLine();            chatClient.sendInfo(s);        }    }}

运行结果

以上是"Java基于NIO如何实现群聊系统"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

服务 服务器 消息 客户 通道 客户端 处理 数据 阻塞 系统 内容 用户 篇文章 事件 字符 字符串 属性 方法 端口 构造器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网的科技创新 深圳互联网络科技有限公司 苏州互联网科技贷款公司 融势互联网科技 有木互联网科技 广西拼得多互联网科技有限公司 太原新华互联网科技学校怎么样 上海电发互联网科技有限公司 博兴的互联网电子科技公司 哈尔滨新华互联网科技学院 重庆互联网医院沙龙医盟信息科技 互联网科技公司有风险吗 呼和浩特新华互联网科技学院 电子科技大学互联网创业大赛 2021世界互联网领先科技成果发布 互联网的科技体现在哪里 广东猫王互联网科技有限公司电话 科技美学互联网 艺术 互联网科技企业文化 前海云享互联网科技 耶加雪菲 互联网科技公司 重生之互联网科技帝国 卓越科技互联网 招聘 中国科技互联网公司收入 南山科技园互联网公司有哪些 黑科技闪耀互联网之光 迪庆互联网科技招生 众安科技工业互联网合作 城市宝互联网科技有限公司
0