Java NIO怎么实现聊天室功能
发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码里面已经包含了必要的
千家信息网最后更新 2025年11月16日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) { Iterator iterator = 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安全错误
数据库的锁怎样保障安全
阿里云手游服务器
网络技术考研的难度
育碧的服务器在那里
mt 4手机版登录服务器
换路由器后无法连接公司服务器
网络安全意识不可缺是什么
shell 按行取数据库
监控 服务器 西门子
学校社团网络技术部考核
天空卫士网络安全厦门
深圳软件开发者价钱
大学生英语辩论数据库
SQL数据库入门级微单
思云3d点歌机连不上服务器
鹰潭绿盟网络安全技术有限公司
成都软件开发招聘
做网络安全行业的销售
石家庄互联网科技公司集中在哪里
奥拉星一共几个服务器
vba如何获取数据库中表
英文期刊数据库ei
软件开发真实情况
软件开发初步怎么做
天空卫士网络安全厦门
重庆物联网数显钟服务器
序列比对数据库搜索工具有哪些
通用应用软件开发
中班网络安全教育简讯
网络安全法考试开展情况
北京华夏网络技术有限公司