首页 > 作文

Java基于NIO实现群聊系统

更新时间:2023-04-03 22:27:56 阅读: 评论:0

本文实例为大家分享了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.lectionkey;import java.nio.channels.lector;import java.nio.channels.rversocketchannel;import java.nio.channels.socketchannel;import java.util.iterator;public class groupchatrver {    //定义属性    private lector lector;    private rversocketchannel listenchannel;    private static final int port = 6667;    //构造器    //初始化工作    public groupchatrver() {        try {            //得到选择器            lector = lector.open();            //rversocketchannel            listenchannel = rversocketchannel.open();            //绑定端口            listenchannel.socket().bind(new inetsocketaddress(port));            //设置非阻塞模式            listenchannel.configureblocking(fal);            //将该 listenchannel 注册到 lector            listenchannel.register(lector, lectionkey.op_accept);        } catch (ioexception e) {            e.printstacktrace();        }    }    public void listen() {        try {            //循环处理            while (true) {                int count = lector.lect();                if (count > 0) { //有事件处理                    // 遍历得到 lectionkey 集合                    iterator<lectionkey> iterator = lector.lectedkeys().iterator();                    while (iterator.hasnext()) {                        //取出 lectionkey                        lectionkey key = iterator.next();                        //监听到 accept                        if (key.isacceptable()) {                            socketchannel sc = listenchannel.accept();                            sc.configureblocking(fal);                            //将该 sc 注册到 letor                            sc.register(lector, lectionkey.op_read);                            //提示                            system.out.println(sc.getremoteaddress() + " 上线 ");                        }                        if (key.isreadable()) {//通道发送read事件,即通道是可读的状态                            // 处理读(专门写方法..)                            readdata(key);                        }                        //当前的 key 删除,防止重复处理                        iterator.remove();                    }                } el {                    system.out.println("等待....");                }            }        } catch (exception e) {            e.printstacktrace();        } finally {            //发生异常处理....        }    }    //读取客户端消息    public void readdata(lectionkey 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);                //向其它的客户端转发消息(去掉自己),专门写一个方法来处理                ndinfotootherclients(msg, channel);            }        } catch (ioexception e) {            try {                system.out.println(channel.getremoteaddress() + "离线了..");                //取消注册                key.cancel();                //关闭通道                channel.clo();            } catch (ioexception e2) {                e2.printstacktrace();            }        }    }    //转发消息给其它客户(通道)    private void ndinfotootherclients(string msg, socketchannel lf) throws ioexception {        system.out.println("服务器转发消息中...");        //遍历所有注册到 lector 上的 socketchannel,并排除 lf        for (lectionkey key : lector.keys()) {            //通过 key 取出对应的 socketchannel            channel targetchannel = key.channel();            //排除自己            if (targetchannel instanceof socketchannel && targetchannel != lf) {                //转型                socketchannel dest = (socketchannel) targetchannel;                //将 msg 存储到 buffer                bytebuffer buffer = bytebuffer.wrap(msg.getbytes());                //将 buffer 的数据写入通道                dest.write(buffer);            }        }    }    public static void main(string[] args) {        //创建服务器对象        groupchatrver groupch槛菊愁烟兰泣露atrver = new groupchatrver();        groupchatrver.listen();    }}

// 客户端:

package com.atguigu.nio.groupchat;~~import java.io.ioexception;import java.net.inetsocketaddress;import java.nio.bytebuffer;import java.nio.channels.lectionkey;import java.nio.channels.lector;import java.nio.channels.socketchannel;import java.util.iterator;import java.utilliyu.scanner;public class groupchatclient {    //定义相关的属性    private final string host = "127.0.0.1";//服务器的ip    private final int port = 6667;//服务器端口    private lector lector;    private socketchannel socketchannel;    private string urname;    //构造器,完成初始化工作    public groupchatclient() throws ioexception {                lector = lector.open();        //连接服务器        socketchannel = socketchannel.open(new inetsocketaddress(host, port));        //设置非阻塞        socketchannel.configureblocking(fal);        //将 channel 注册到lector        socketchannel.register(lector, lectionkey.op_read);        //得到 urname        urname = socketchannel.getlocaladdress().tostring().substring(1);        system.out.println(urname + " is ok...");    }    //向服务器发送消息    public void ndinfo(string info) {        info = urname + " 说:" + info;        try {            socketchannel.write(bytebuffer.wrap(info.getbytes()));        } catch (ioexception e) {            e.printstacktrace();        }    }    //读取从服务器端回复的消息    public void readinfo() {        try {            int readchannels = lector.lect();            if (readchannels > 0) {//有可以用的通道                iterator&l颠倒黑白小游戏t;lectionkey> iterator = lector.lectedkeys().iterator();                while (iterator.hasnext()) {                    lectionkey 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(); //删除当前的 lectionkey,防止重复操作            } el {                //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.ndinfo(s);        }    }}

运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。

本文发布于:2023-04-03 22:27:55,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/0910cfd46db638f3dca8f5021aaf28bb.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Java基于NIO实现群聊系统.doc

本文 PDF 下载地址:Java基于NIO实现群聊系统.pdf

上一篇:Vue Element
下一篇:返回列表
标签:通道   消息   服务器   客户端
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图