Java基于NIO实现群聊功能
程序员文章站
2022-03-15 19:32:49
本文实例为大家分享了java基于nio实现群聊功能的具体代码,供大家参考,具体内容如下一、群聊服务器package com.dashu.netty.group_chat;import java.net...
本文实例为大家分享了java基于nio实现群聊功能的具体代码,供大家参考,具体内容如下
一、群聊服务器
package com.dashu.netty.group_chat; import java.net.inetsocketaddress; import java.nio.bytebuffer; import java.nio.channels.*; import java.nio.charset.standardcharsets; import java.util.iterator; public class groupchatserver { /** * 初始化选择器 */ private selector selector; /** * 初始化服务器网络通道 */ private serversocketchannel serversocketchannel; /** * 端口 */ private static final int port = 6666; /** * 构造方法 */ public groupchatserver() { try { //获取选择器 selector = selector.open(); //获取服务器网络通道 serversocketchannel = serversocketchannel.open(); //网络地址 inetsocketaddress inetsocketaddress = new inetsocketaddress(port); //服务器网络通道绑定网络地址 serversocketchannel.socket().bind(inetsocketaddress); //设置服务器网络通道非阻塞 serversocketchannel.configureblocking(false); //将服务器网络通道注册到选择器上,绑定连接请求事件 serversocketchannel.register(selector, selectionkey.op_accept); } catch (exception e) { e.printstacktrace(); } } /** * 监听客户端请求事件 */ public void listen() { try { //无限循环 while (true) { //获取请求数 int count = selector.select(); //count大于0,则代表有请求进来 if (count > 0) { //获取请求集 iterator<selectionkey> selectionkeyiterator = selector.selectedkeys().iterator(); //遍历请求集 while (selectionkeyiterator.hasnext()) { //得到请求 selectionkey selectionkey = selectionkeyiterator.next(); //连接请求 if (selectionkey.isacceptable()) { //获取客户端网络通道 socketchannel socketchannel = serversocketchannel.accept(); //设置客户端网络通道非阻塞 socketchannel.configureblocking(false); //将客户端网络通道注册到选择器上 socketchannel.register(selector, selectionkey.op_read); system.out.println(socketchannel.getremoteaddress() + "上线了"); } //信息读取请求 if (selectionkey.isreadable()) { //客户端信息读取 readdata(selectionkey); } //移除请求 selectionkeyiterator.remove(); } } else { system.out.println("等待..."); } } } catch (exception e) { e.printstacktrace(); } } /** * 客户端信息读取 * * @param selectionkey */ private void readdata(selectionkey selectionkey) { //初始化客户端网络通道 socketchannel socketchannel = null; try { //获取客户端网络通道 socketchannel = (socketchannel) selectionkey.channel(); //创建缓冲区 bytebuffer bytebuffer = bytebuffer.allocate(1024); //读取客户端网络通道中的数据到缓冲区 int count = socketchannel.read(bytebuffer); //判断缓冲区中是否有数据 if (count > 0) { //将缓冲区的数据转换位字符串 string message = new string(bytebuffer.array()); system.out.println(message.trim()); //将信息群发到其他客户端 sendinfotootclients(message, socketchannel); } } catch (exception e) { e.printstacktrace(); } } /** * 将信息群发到其他客户端 * * @param message * @param socketchannel */ private void sendinfotootclients(string message, socketchannel socketchannel) { //获取所有注册到选择器的客户端,并遍历 for (selectionkey selectionkey : selector.keys()) { //获取通道 channel channel = selectionkey.channel(); //判断通道是否属于socketchannel,同时不等于发送信息的客户端 if (channel instanceof socketchannel && channel != socketchannel) { //通道转换 socketchannel sc = (socketchannel) channel; //将信息写入缓冲区 bytebuffer bytebuffer = bytebuffer.wrap(message.getbytes(standardcharsets.utf_8)); try { //将缓冲区的数据写入通道 sc.write(bytebuffer); } catch (exception e) { e.printstacktrace(); } } } } public static void main(string[] args) { groupchatserver groupchatserver = new groupchatserver(); system.out.println("服务器启动,开始监听客户端请求..."); groupchatserver.listen(); } }
二、客户端
package com.dashu.netty.group_chat; 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.nio.charset.standardcharsets; import java.util.iterator; import java.util.scanner; public class groupchatclient { /** * 网络连接地址 */ private final string host = "127.0.0.1"; /** * 端口 */ private final int port = 6666; /** * 初始化选择器 */ private selector selector; /** * 初始化网络通道 */ private socketchannel socketchannel; /** * 用户名 */ private string username; public groupchatclient() { try { //获取选择器 selector = selector.open(); //获取服务器网络地址 inetsocketaddress inetsocketaddress = new inetsocketaddress(host, port); //获取网络通道 socketchannel = socketchannel.open(inetsocketaddress); //设置网络通道非阻塞 socketchannel.configureblocking(false); //将网络通道注册到选择器 socketchannel.register(selector, selectionkey.op_read); //获取用户名 system.out.println("请输入用户名:"); scanner scanner = new scanner(system.in); username = scanner.nextline(); system.out.println(username + " 进入群聊..."); } catch (exception e) { e.printstacktrace(); } } /** * 向服务器发送信息 * * @param message */ public void sendinfo(string message) { message = username + ":" + message; try { //向通道写入数据 socketchannel.write(bytebuffer.wrap(message.getbytes(standardcharsets.utf_8))); } catch (exception e) { e.printstacktrace(); } } /** * 读取服务器发来的信息 */ public void readinfo() { try { //获取请求数 int count = selector.select(); if (count > 0) { //获取请求集 iterator<selectionkey> selectionkeyiterator = selector.selectedkeys().iterator(); //遍历请求集 while (selectionkeyiterator.hasnext()) { //获取请求 selectionkey selectionkey = selectionkeyiterator.next(); //判断位读请求 if (selectionkey.isreadable()) { //获取通道 socketchannel sc = (socketchannel) selectionkey.channel(); //创建缓冲区 bytebuffer bytebuffer = bytebuffer.allocate(1024); //读取通道的数据到缓冲区 sc.read(bytebuffer); //缓冲区数据转字符串 string message = new string(bytebuffer.array()); //输出 system.out.println(message.trim()); } //移除已完成请求 selectionkeyiterator.remove(); } } } catch (exception e) { e.printstacktrace(); } } public static void main(string[] args) { groupchatclient groupchatclient = new groupchatclient(); /** * 开启一个线程,每3秒读取一次服务器发来的信息 */ new thread() { @override public void run() { while (true) { groupchatclient.readinfo(); try { thread.sleep(3000); } catch (exception e) { e.printstacktrace(); } } } }.start(); //信息输入 scanner scanner = new scanner(system.in); system.out.println("请输入信息:"); while (scanner.hasnextline()) { string s = scanner.nextline(); //信息发送 groupchatclient.sendinfo(s); system.out.println("请输入信息:"); } } }
三、效果图
1、服务器
2、客户端01
3、客户端02
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 惹到爆笑一片的二货男女