本文实例为大家分享了java基于nio实现群聊模式的具体代码,供大家参考,具体内容如下
client
package com.qst.chat;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.ut悲愤欲绝的绝是什么意思il.scanner;public class groupchatclient { private final int port = 9999; private final string host = "localhost"; private socketchannel channel; private static lector lector; private string name; public groupchatclient() throws ioexception { lector = lector.open(); // 连接服务器 channel = socketchannel.open(new inetsocketaddress(host, port)); // 设置非阻塞 channel.configureblocking(fal); // 将channel 注册到lector channel.register(lector, lectionkey.op_read); name = channel.getlocaladdress().tostring().substring(1); system.out.println(name + "is ok ...."); } // 向服务器发送消息 public void ndto(string msg) { bytebuffer buffer = bytebuffer.wrap((name+":"+msg).getbytes()); try { channel.write(buffer); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } // 读取从服务器端回复的消息 public static void getinfo() { try { if(lector.lect() >0) { iterator<lectionkey> iterator = lector.lectedkeys().iterator(); while(iterator.hasnext()) { lectionkey key = iterator.next(); if(key.isreadable()) { // 得到通道 socketchannel sc = (socketchannel) key.channel(); bytebuffer buffer = bytebuffer.allocate(1024); int len; // 把读到的缓冲区的数据转成字符串 while((len = sc.read(buffer)) > 0) { system.out.println(new string(buffer.array())); } } } // 删除当前的lectionkey, 防止重复操作 iterator.remove(); } } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } public static void main(string[] args) { try { groupchatclient client = new groupchatclient(); new thread() { public void run() { while(true) { try { thread.sleep(3000); groupchatclient.getinfo(); } catch (interruptedexception说说2021 e) { // todo auto-generated catch block e.printstacktrace(); } } }; }.start(); scanner sc = new scanner(system.in);// while(true) {// string name = sc.nextline();// client.ndto(name);// } while(sc.hasn云南体育运动职业技术学院extline()) { string s = sc.nextline(); client.ndto(s); } } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } }}
rver端
package com.qst.chat;import java.io.ioexception;import java.net.inetaddress;import java.net.inetsocketaddress;import java.net.rversocket;import java.net.socket;import java.nio.bytebuffer;import java.nio.channels.lectablechannel;import java.nio.channels.lectionkey;import java.nio.channels.lector;import java.nio.channels.rversocketchannel;import java.nio.channels.socketchannel;import java.time.chrono.isochronology;import java.util.iterator;import com.sun.accessibility.internal.resources.accessibility;import sun.print.resources.rviceui;public class groupchatrver { private static rversocketchannel socketchannel; private static socket socket; private static lector lector; private static socketchannel accept; public groupchatrver() throws ioexception { socketchannel = rversocketchannel.open(); lector = lector.open(); // 绑定端口 socketchannel.socket().bind(new inetsocketaddress(9999)); // 设置非阻塞模式 socketchannel.configureblocking(fal); // 将该通道 注册到lector socketchannel.register(lector, lectionkey.op_accept); } // 监听 public static void listen() { system.out.println("监听线程: " + thread.currentthread().getname()); try { while (lector.lect() > 0) { iterator<lectionkey> iterator = lector.lectedkeys().iterator(); if (iterator.hasnext()) { // 遍历得到lectionkey 集合 lectionkey next = iterator.next(); if (next.isacceptable()) { next.channel(); // socketchannel = (rversocketchannel) next.channel(); socketchannel accept = socketchannel.accept(); accept.configureblocking(fal); accept.register(lector, lectionkey.op_read); system.out.println(accept.getremoteaddress()+" 上线 了。。。"); } if (next.isreadable()) { readdate(next); } // 移除当前的next,防止重复处理 iterator.remove(); // system.out.println("未发现"); } } } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } // 读取客户端消息 public static void readdate(lectionkey key) { try { accept = (socketchannel) key.channel(); bytebuffer buffer = bytebuffer.allocate(1024); int len = accept.read(buffer); if (len > 0) { buffer.flip(); string msg = new string(buffer.array()); system.out.println("ur = " + msg); // 向其它的客户端转发消息(去掉自己) ndtoall(msg, accept); buffer.clear(); } } catch (ioexception e) { // todo auto-generated catch block try { string msg = accept.getremoteaddress().tostring(); // 取消注册 key.cancel(); // 关闭通道 accept.clo(); system.out.println(msg + "离线了"); } catch (ioexception e1) { // todo 康燕auto-generated catch block e1.printstacktrace(); } // e.printstacktrace(); } finally { // todo: handle finally clau } } public static void ndtoall(string msg, socketchannel ssc) { for (lectionkey ss : lector.keys()) { // 通过 key 取出对应的 socketchannel lectablechannel channel = ss.channel(); // 排除自己 if (channel instanceof socketchannel && channel != ssc) { // 转型 socke老人与海小说下载tchannel sh = (socketchannel) channel; // 转存到buffer bytebuffer wrap = bytebuffer.wrap(msg.getbytes()); try { // 写入通道 sh.write(wrap); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } } } public static void main(string[] args) throws ioexception { groupchatrver rver = new groupchatrver(); groupchatrver.listen(); }}
key.isacceptable()进行接入 操作的时候, 获取通道有两种方式
1、 通过lector获取 (lector key) socketchannel = (rversocketchannel) key.channel();
建立连接 socketchannel .accept();
2、定义一个全局变量
在进行初始化的时候,存储(socketchannel = rversocketchannel.open();)
建立连接 socketchannel .accept();
key.isreadable() 当进行到读入操作的时候( ) lectionkey key accept = (socketchannel) key.channel();
服务器启动,客户端启动
客户端发送消息
启动第二个客户端
两个客户端相互通信
离线信息显示
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。
本文发布于:2023-04-03 22:24:24,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/4490e508e82acecbb352c24d688fb7c9.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:java基于NIO实现群聊模式.doc
本文 PDF 下载地址:java基于NIO实现群聊模式.pdf
留言与评论(共有 0 条评论) |