Java NIO怎么实现聊天室功能
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码里面已经包含了必要的
千家信息网最后更新 2025年02月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安全错误
数据库的锁怎样保障安全
管壳式换热器软件开发
plsql 数据库连接
嵌入式设备使用redis数据库
河北语音网络技术分类产品介绍
手机同花顺连不到服务器
新乡市新一网络技术有限公司
老版lol服务器图标
租车软件开发计划书需求分析报告
华为服务器不能设置同网段ip
建立第三方评价数据库
疫情网络安全宣传画手绘
飞瓜数据库技术
节能网络技术有哪些
免费公司软件开发
失落的方舟那个服务器好
塔式服务器功能
工业信息化部网络安全局刘超
sql数据库连接失败
书目数据库是全文数据库吗
软件开发为什么别人工资高
浙江无级互联网科技有限公司
常州小型软件开发咨询报价
互联网之光高科技博览会
软件开发人员保密管理
济南博赛网络技术公司招聘
武昌订制软件开发电话
众人网络安全技术公司怎么样
用什么软件开发手机app
计算机与网络技术的重要性
华为电信中国系统网络安全