Java NIO怎么实现聊天室功能
发表于:2024-12-02 作者:千家信息网编辑
千家信息网最后更新 2024年12月02日,这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码里面已经包含了必要的
千家信息网最后更新 2024年12月02日Java NIO怎么实现聊天室功能
这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
具体内容如下
代码里面已经包含了必要的注释,这里不详述了。实现了基本的聊天室功能。
常量类:
public class Constant { public static final int serverPort = 44444;}
服务端:
package server; import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.ClosedChannelException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Iterator;import java.util.Set; import constant.Constant; public class SocketServer { private Charset charset = Charset.forName("UTF-8"); private ServerSocketChannel serverSocketChannel; private Selector serverSocketSelector; private SelectionKey serverRegisterKey; private ByteBuffer buffer = ByteBuffer.allocate(1024); public static void main(String[] args) throws IOException { new SocketServer().openServer(new InetSocketAddress(Constant.serverPort)); } public void openServer(SocketAddress address) throws IOException { init(address); handle(); } private void init(SocketAddress address) throws IOException { serverSocketSelector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverRegisterKey = serverSocketChannel.register(serverSocketSelector, SelectionKey.OP_ACCEPT); serverSocketChannel.socket().bind(address); } private void handle() throws IOException { System.out.println("服务端open"); while (serverSocketSelector.select() > 0) { Iteratoriterator = serverSocketSelector.selectedKeys().iterator(); // 为什么这里要用迭代器,而不用增强for循环之类的呢?是因为这里获得一个key之后,要对其进行移除,避免二次处理,造成影响 while (iterator.hasNext()) { dispatch(iterator.next()); iterator.remove(); } } } private void dispatch(SelectionKey key) throws IOException { if (key.isAcceptable()) { accept(key); } else if (key.isReadable()) { readMessage(key); } else if (key.isValid() && key.isWritable()) { writeMessage(key); } } private void accept(SelectionKey key) throws IOException, ClosedChannelException { // 主要的是,接收事件是发生在服务器这边的,所以这边的通道要强转为ServerSocketChannel ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); // 同时再给该通道注册选择器,监听的内容的读取 client.register(serverSocketSelector, SelectionKey.OP_READ); } private void readMessage(SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); client.read(buffer); // 调整为读取模式 buffer.flip(); String content = charset.decode(buffer).toString(); // 压缩空间,即抛弃已经读取的内容(实际上还在里面,只是处于等待被覆盖状态) buffer.compact(); // 这里可以根据业务逻辑,设置不设置都可以,但是这里想接受到消息后立马回复一条消息,所以设置下一次感兴趣的(监听)事件为写 key.interestOps(SelectionKey.OP_WRITE); // 设置系统回复信息 key.attach("系统已经收到你的消息\n"); // 开始广播这个客户端的内容到其他客户端 broadcast(key, content); } private void broadcast(SelectionKey self, String content) throws IOException { Set selectedKeys = self.selector().keys(); for (SelectionKey key : selectedKeys) { // 不能发送给自己,也不要服务器自己本身对这个有反应 if (key != self && key != serverRegisterKey) { String oldMessage = (String) key.attach(null); // 如果有旧消息的话,在下一次发送时,连同旧消息一起发送 key.attach(oldMessage != null ? oldMessage + content : content); key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); } } } private void writeMessage(SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); // 获取发给这个客户端的消息,并清空消息 client.write(charset.encode((String) key.attach(null))); key.interestOps(SelectionKey.OP_READ); }}
客户端(包含了Socket版本和SocketChannel版本):
package client; import java.io.IOException;import java.net.InetSocketAddress;import java.net.Socket;import java.net.UnknownHostException;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Scanner; import constant.Constant; public class SocketClient { public static void main(String[] args) throws IOException { nioVersion(); // ioVersion(); } private static void ioVersion() throws UnknownHostException, IOException { System.out.println("客户端"); final Socket socket = new Socket(); socket.connect(new InetSocketAddress(Constant.serverPort)); new Thread() { @Override public void run() { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String line = scanner.nextLine(); try { socket.getOutputStream().write((line + "\n").getBytes("UTF-8")); } catch (IOException e) { e.printStackTrace(); } } scanner.close(); try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }.start(); new Thread() { @Override public void run() { try { Scanner scanner = new Scanner(socket.getInputStream(), "utf-8"); while (scanner.hasNext()) { String line = scanner.nextLine(); System.out.println("收到消息:" + line); } scanner.close(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } private static void nioVersion() throws IOException { Charset charset = Charset.forName("UTF-8"); System.out.println("客户端"); SocketChannel socketChannel = SocketChannel.open(); // 设置为非阻塞模式 socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(Constant.serverPort)); while (true) { if (socketChannel.finishConnect()) { new Thread() { @Override public void run() { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String input = scanner.nextLine(); try { socketChannel.write(charset.encode(input)); } catch (IOException e) { e.printStackTrace(); } } scanner.close(); } }.start(); new Thread() { ByteBuffer dst = ByteBuffer.allocate(1024); @Override public void run() { while (true) { try { int len = socketChannel.read(dst); if (len > 0) { dst.flip(); System.out.println("收到消息:" + charset.decode(dst)); dst.compact(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); return; } } } }
感谢你能够认真阅读完这篇文章,希望小编分享的"Java NIO怎么实现聊天室功能"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
消息
客户
内容
客户端
篇文章
服务
功能
聊天室
UTF-8
事件
兴趣
同时
服务器
模式
版本
端的
系统
通道
监听
必要
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
延安软件开发群
怀旧服服务器战士输出
华为云服务器部署网页
怎样判断数据库是否存在
微信用什么软件开发小程序
河北高科技软件开发价格表格
所有数据库安全技术
网络安全剧本编排
南京建设智慧学校软件开发
网信河北网络安全法题库及答案
海顿服务器
洛阳铁路法学网络安全
win10 数据库 下载
中专网络技术怎么样
即时通讯软件开发立项报告
数据库安全的手段
守望先锋服务器配音
全球做网络安全防护的公司
支付宝网络技术有限公司客服
服务器硬件架构设计
松江区信息化软件开发代理品牌
网络安全维护评测
纪委监委网络安全宣传活动
杭州erp软件开发怎么选
服务器的安全
海南州网络技术产品介绍
郑州网络安全比赛视频
河北金盾网络技术有限公司
梦幻西游新服务器列表
明日之后四字服务器下载和苹果