【深入理解Java IO流0x0A】NIO实战-网络聊天室

本篇博客将进行NIO编程实战,实现一个简单聊天室。
我们来通过 SocketChannel 和 ServerSocketChannel 实现一个 0.1 版的聊天室,先说一下需求,比较简单,服务端启动监听客户端请求,当客户端向服务器端发送信息后,服务器端接收到后把客户端消息回显给客户端,比较呆瓜,但可以先来看一下。
image.png
来看服务端代码:

@Slf4j
public class ChatServer {private Selector selector;private ServerSocketChannel serverSocketChannel;private static final int PORT = 8080;public static void main(String[] args) {new ChatServer().start();}public ChatServer(){try {// 创建一个 ServerSocketChannel,并将其绑定到指定端口serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(PORT));// 设置为非阻塞模式serverSocketChannel.configureBlocking(false);// 创建一个Selector,并将ServerSocketChannel注册到它上面// 监听OP_ACCEPT事件(等待客户端连接)selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);log.info("聊天室服务端启动了:"+PORT);} catch (IOException e) {e.printStackTrace();}}public void start(){try {// 无限循环,等待连接while(true){// 等待已注册的通道中有事件发生if(selector.select()>0){Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while(iterator.hasNext()){// 获取到发生事件的通道的SelectionKeySelectionKey key = iterator.next();iterator.remove();handleKey(key);}}}} catch (IOException e) {e.printStackTrace();}}// 判断SelectionKey的事件类型private void handleKey(SelectionKey key) throws IOException{// 如果是OP_ACCEPT事件,说明有新的客户端连接进来。// 接受新的连接,并将新连接的SocketChannel注册到 Selector上,监听OP_READ事件if(key.isAcceptable()){SocketChannel socketChannel = serverSocketChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector,SelectionKey.OP_READ);log.info("客户端连接上了:"+socketChannel.getRemoteAddress());}else if(key.isReadable()){  // 如果是OP_READ事件,说明客户端发送了消息。读取客户端发送的消息,并将其返回给客户端SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int len = socketChannel.read(buffer);if(len>0){buffer.flip();String message = new String(buffer.array(),0,len);log.info("客户端说:"+message);String responseMsg = "服务端回复:"+message;socketChannel.write(ByteBuffer.wrap(responseMsg.getBytes()));}}}
}

接下来是客户端:

@Slf4j
public class ChatClient {private Selector selector;private SocketChannel socketChannel;private static final String HOST = "localhost";private static final int PORT = 8080;public static void main(String[] args) {new ChatClient().start();}public ChatClient(){try {selector = Selector.open();// 创建一个 SocketChannel,并连接到指定的服务器地址和端口socketChannel = SocketChannel.open(new InetSocketAddress(HOST,PORT));socketChannel.configureBlocking(false); // 设置为非阻塞模式// 将SocketChannel注册到selector上面,监听OP_READ事件(等待接收服务器的消息)socketChannel.register(selector, SelectionKey.OP_READ);log.info("连接到聊天室了");} catch (IOException e) {e.printStackTrace();}}private void start() {// 启动一个新线程用于new Thread(()->{try {while(true){// 等待已注册的通道中有事件发生if(selector.select()>0){// 获取到发生事件的通道的 SelectionKeyfor(SelectionKey key:selector.selectedKeys()){selector.selectedKeys().remove(key);// 如果是 OP_READ 事件,说明服务器发送了消息。读取服务器发送的消息,并在控制台显示。if(key.isReadable()){readMessage();}}}}} catch (Exception e) {e.printStackTrace();}}).start();try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){String input;while((input=reader.readLine())!=null){sendMessage(input);}}catch (IOException e){e.printStackTrace();}}private void sendMessage(String message) throws IOException{if(message!=null && !message.trim().isEmpty()){ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());socketChannel.write(buffer);}}private void readMessage() throws IOException{ByteBuffer buffer = ByteBuffer.allocate(1024);int len = socketChannel.read(buffer);if(len>0){buffer.flip();String message = new String(buffer.array(),0,len);log.info(message);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/310022.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion之文生图模型训练

1、数据准备 提前准备好一组相关的照片。 在线的图片处理网站 BIRME - Bulk Image Resizing Made Easy 2.0 (Online & Free) 将图片转成统一大小&#xff0c;支持批量处理&#xff0c;效率高 2、生成提示词 进入stable diffusion webui页面 旧版直接使用 train/proproc…

SSH安全设置

今天发现自己的公有云服务器被攻击了 然后查看了登录日志&#xff0c;如上图 ls -sh /var/log/secure vim /var/log/secure然后增加了安全相关的设置 具体可以从以下方面增加安全性&#xff1a; 修改默认SSH端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及限…

简单工厂模式设计实验

实验内容&#xff1a; 楚锋软件公司欲基于Java 语言开发一套图表库&#xff0c;该图表库可以为应用系统提供各种不同外观的图表&#xff0c;例如柱状图、饼状图、折线图等。楚锋软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库&#xff0c;而且可以较为…

【Linux学习】初识Linux指令(二)

文章标题 1.rm 指令2.man指令3.nano指令4.cp指令5.mv指令6.alias指令7. cat与8.echo指令 ⚶文章简介 ⚶本篇文章继上篇文章Linux指令讲解&#xff0c;本篇文章主要会涉及到的指令会有&#xff1a;rm指令与 *&#xff08;通配符&#xff09;的搭配使用&#xff0c;man指令&…

找出mongodb的jumbo块并进行分裂

https://www.cnblogs.com/abclife/p/15968628.html 根据这篇文档中的脚本&#xff0c;在我们自己的环境中跑了下&#xff0c;第一次跑的结果如下&#xff1a; 运行完上面跑出的split脚本后&#xff0c;还是存在jumbo块&#xff0c;第二次跑出的结果&#xff1a; 从上面结果可以…

深入探索:Zookeeper+消息队列(kafka)集群

目录 前言 一、Zookeeper概述 1、Zookeeper概念 2、Zookeeper 特点 3、Zookeeper工作机制 4、Zookeeper 选举机制 4.1 第一次启动选举机制 4.2 非第一次启动选举机制 5、Zookeeper 数据结构 6、Zookeeper 应用场景 二、部署 Zookeeper 集群 1、环境部署 2、安装 z…

【HTML】简单制作一个动态变色光束花

目录 前言 开始 HTML部分 效果图 ​编辑​编辑​编辑​编辑总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建一个文本文档&#xff0c;其中HTML的文件名改为[index.html]&a…

比特币突然暴跌

作者&#xff1a;秦晋 周末愉快。 今天给大家分享两则比特币新闻&#xff0c;也是两个数据。一则是因为中东地缘政治升温&#xff0c;传统资本市场的风险情绪蔓延至加密市场&#xff0c;引发加密市场暴跌。比特币跌至66000美元下方。杠杆清算金额高达8.5亿美元。 二则是&#x…

交流电子负载解决方案

交流电子负载是一种可以模拟真实负载的设备&#xff0c;它可以接收交流电源输入&#xff0c;并以一定的电流和电压进行输出。这种设备在电力系统、电子设备研发、生产和质量控制等多个领域都有广泛的应用。以下是一些关于交流电子负载解决方案的建议。 选择合适的设备&#xff…

锁策略总结

锁策略 悲观锁和乐观锁 乐观锁和悲观锁不是具体类型的锁而是指两种不同的对待加锁的态度&#xff0c;这两个锁面对锁冲突的态度是相反的。 乐观锁&#xff1a;认为不存在很多的并发操作&#xff0c;因此不需要加锁。悲观锁&#xff1a;认为存在很多并发操作&#xff0c;因此需…

FPGA - 以太网UDP通信(二)

一&#xff0c;引言 前文链接&#xff1a;FPGA - 以太网UDP通信&#xff08;一&#xff09; 在上文章中介绍了以太网简介&#xff0c;以太网UDP通信硬件结构&#xff0c;以及PHY芯片RGMII接口-GMII接口转换逻辑&#xff0c;接下来介绍UDP通信结构框图以及数据链路层&#xff…

【详细讲解下Photoshop】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

MySQL练习题

有三个表&#xff0c;表S&#xff08;学生表&#xff09;&#xff0c;C&#xff08;课程表&#xff09;&#xff0c;SSC&#xff08;学生选课表&#xff09; S&#xff08;SNO&#xff0c;SNAME&#xff09;代表&#xff08;学号&#xff0c;姓名&#xff09; C&#xf…

[MySQL]数据库原理8——喵喵期末不挂科

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

NVM的安装与配置

目录 一、简介二、下载2.1、windows环境下载地址2.2、安装 三、配置3.1、查看可安装版本3.2、安装版本3.3、使用和切换版本3.4、模块配置 四、其他4.1、全局安装pnpm4.2、常用nvm命令 一、简介 NVM&#xff0c;全称为Node Version Manager&#xff0c;是一个流行的命令行工具&a…

k8s控制器(五)_____DaemonSet

DaemonSet控制器 DaemonSet控制器是Kubernetes中的一种控制器&#xff0c;用于确保集群中的每个节点都运行一个Pod的副本。它通常用于在整个集群中部署一些系统级别的服务&#xff1a; 在每一个node节点运行一个存储服务&#xff0c;例如gluster&#xff0c;ceph。在每一个no…

模型预测控制MPC(2)—— 无约束线性MPC

前文&#xff1a;模型预测控制MPC&#xff08;1&#xff09;—— 基础概念参考&#xff1a;模型预测控制&#xff08;2022春&#xff09;本文从偏控制的角度介绍无约束线性MPC方法&#xff0c; x , u , J x,u,J x,u,J 分别代表状态、动作和代价函数 文章目录 1. 问题定义1.1 多…

P2P通信基本原理

在数字世界的脉络中&#xff0c;点对点&#xff08;P2P&#xff09;技术如同一条悄无声息的河流&#xff0c;流经信息的每个角落&#xff0c;连接着世界各地的计算机和设备。这种去中心化的网络模型&#xff0c;不仅打破了传统的客户端-服务器架构的界限&#xff0c;还赋予了数…

DC-5渗透测试复现

DC-5渗透测试复现 目的&#xff1a; 获取最高权限以及5个flag 过程&#xff1a; 信息打点-文件包含漏洞-弹shell- scren-4.0.5提权 环境&#xff1a; 攻击机&#xff1a;kali(192.168.85.136) 靶机&#xff1a;DC_3(192.168.85.134) 复现&#xff1a; 一.信息收集 nma…

DC-2渗透测试复现

DC-2渗透测试复现 目的&#xff1a; 获取最高权限以及5个flag 过程&#xff1a; 信息打点-ssh连接-git提权 环境&#xff1a; 攻击机&#xff1a;kali(192.168.85.136) 靶机&#xff1a;DC_2(192.168.85.132) 复现&#xff1a; 一.信息收集 nmap -sP 192.168.85.0/24 …