Netty-基于NIO实现群聊系统-逐步搭建

Synopsys工具filter命令:从数据筛选到高效IC设计的实战指南 在数字集成电路设计流程中,数据筛选与查询是工程师处理海量网表、时序报告和设计约束的核心需求。其原理在于通过声明式查询语言,直接对设计对象(如单元、网络、路径)的属性进行逻辑判断与模式匹配,从而精准定位目标。这种技术价值在于将工程师从繁琐的过程式脚本循环中解放出来,大幅提升代码可读性与运行效率,直接调用工具内置的高性能查询引擎。在实际应用场景中,它广泛用于物理与时序联合分析、层次化模块操作、动态约束生成以及自动化报告生成。本文聚焦于Synopsys工具链中filter命令的高阶用法,深入解析其表达式语法、正则 阅读详情

1、功能介绍

  • 基于NIO实现一个群聊系统,实现服务器端和客户端之间的简单通讯,非阻塞方式
  • 实现多人群聊,客户端的消息可以无阻塞的发给所有的其他用户,也能接收其它用户的消息
  • 服务器端:需要监测用户上线、下线,实现客户端消息转发功能
  • 客户端:通过通道无阻塞的发送消息给其它用户,并接收其他用户的消息

2、系统分析

在这里插入图片描述

  • **服务器端:**服务器启动并监听端口,服务器接收客户端的消息并转发,同时处理客户端上线和离线
  • **客户端:**连接服务器,发送消息,接收服务器转发的消息

3、服务器端实现

package NIO.groupchat;

import com.sun.jdi.event.StepEvent;

import javax.swing.event.ListSelectionListener;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class GroupChatServer {
    //定义相关属性
    private Selector selector;
    private ServerSocketChannel listenChannel;
    private static int PORT = 6667;
    
    //构造器完成初始化工作
    public GroupChatServer(){
        try{
            //得到选择器
            selector = Selector.open();
            //得到ServerSocketChannel
            listenChannel = ServerSocketChannel.open();
            //绑定端口
            listenChannel.socket().bind(new InetSocketAddress(PORT));
            //设置非阻塞模式
            listenChannel.configureBlocking(false);
            //将listenChannel注册到selector
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    
    //监听功能
    public void listen(){
        try{
            //循环处理
            while(true){
                int count = selector.select();
                //有时间需要处理时
                if(count > 0){
                    //遍历得到selectionKey集合
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while(iterator.hasNext()){
                        //取出一个selectionKey
                        SelectionKey key = iterator.next();
                        //当监听到accept时
                        if(key.isAcceptable()){
                            SocketChannel sc = listenChannel.accept();
                            sc.configureBlocking(false);
                            //将sc注册到selector
                            sc.register(selector,SelectionKey.OP_READ);
                            //提醒事项
                            System.out.println(sc.getRemoteAddress()+" 上线");
                        }
                        //通道发送read事件,此时通道是可读状态
                        if(key.isReadable()){
                            readData(key);
                        }
                        //删除当前key,下一次遍历直接到下一个
                        iterator.remove();
                    }
               }else{
                    System.out.println("等待...");
                }
            }   
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            //异常处理
        }
    }
    //读取客户端信息
    private void readData(SelectionKey key) {
        //读取关联的channel
        SocketChannel channel = null;
        try {
            //得到channe
            channel = (SocketChannel)key.channel();
            //创建buffer
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = channel.read(buffer);
            if(count > 0){
                //把缓存区的数据存成字符串
                String msg = new String(buffer.array());
                //输出该消息
                System.out.println("FROM 客户端:"+ msg);
                //向其他客户端转发消息
                sendInfoToOtherClient(msg,channel);
            }
        }catch (IOException e){
            try {
                System.out.println(channel.getRemoteAddress() + "离线了");
                //取消注册
                key.cancel();
                //关闭通道
                channel.close();
            } catch (IOException ee){
                ee.printStackTrace();
            }
        }
    }
    
    //转发消息给其他客户端/的通道
    private void sendInfoToOtherClient(String msg, SocketChannel self) throws IOException{
        System.out.println("服务器转发消息中...");
        //遍历所有注册到selector的SocketChannel,排除发送消息的那个
        for(SelectionKey key : selector.keys()){
            //通过key获取对应的SockeChannel
            Channel targetChannel = key.channel();
            //排除自己
            if(targetChannel instanceof SocketChannel && targetChannel != self){
                //转型
                SocketChannel dest = (SocketChannel)targetChannel;
                //将msg存储到buffer
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
                //将buffer的数据写入信道
                dest.write(buffer);
            }
        }
    }
    
    //主函数
    public static void main(String[] args) {
        //创建服务器对象
        GroupChatServer groupChatServer = new GroupChatServer();
        groupChatServer.listen();
    }
}

4、客户端实现

package NIO.groupchat;

import java.io.IOException;
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.sql.BatchUpdateException;
import java.util.Iterator;
import java.util.Scanner;

/*客户端*/
public class GroupChatClient {
    /*定义相关属性*/
    //服务器IP
    private final String HOST = "127.0.0.1";
    //服务器端口
    private final int POST = 6667;
    private Selector selector;
    private SocketChannel socketChannel;
    private String username;

    //使用构造器完成初始化工作
    public GroupChatClient() throws IOException {
        selector = Selector.open();
        //连接至服务器
        socketChannel = socketChannel.open(new InetSocketAddress("127.0.0.1",POST));
        //设置为非阻塞模式
        socketChannel.configureBlocking(false);
        //将channel注册到selector
        socketChannel.register(selector, SelectionKey.OP_READ);
        //得到用户名
        username = socketChannel.getRemoteAddress().toString().substring(1);
        System.out.println(username + "is ok...");
    }

    //向服务器发送消息
    public void sendInfo(String info){
        info = username + " 说:" + info;
        try {
            socketChannel.write(ByteBuffer.wrap(info.getBytes()));
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    //读取从服务器端回复的消息
    public void readInfo(){
        try{
            int readChannels = selector.select();
            //有可用的通道的时候
            if(readChannels > 0){
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while(iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    if(key.isReadable()){
                        //得到相关的通道
                        SocketChannel sc = (SocketChannel)key.channel();
                        //得到一个Buffer
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        //读取
                        sc.read(buffer);
                        //把读到的缓冲区数据转换成字符串形式
                        String msg = new String(buffer.array());
                        //去除多余首位空格
                        System.out.println(msg.trim());
                    }
                }
                //删除当前,下一次遍历当前的下一个
                iterator.remove();
            }else{
                System.out.println("没有可用通道...");
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    //主程序,进行测试
    public static void main(String[] args) throws Exception {
        //启动客户端
        GroupChatClient groupChatClient = new GroupChatClient();
        //启动一个新线程,每三秒读取从服务器发送的数据
        new Thread(){
            @Override
            public void run(){
                while(true){
                    groupChatClient.readInfo();
                    try {
                        Thread.currentThread().sleep(3000);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //发送数据给服务器
        Scanner scanner = new Scanner(System.in);

        while(scanner.hasNextLine()){
            String str = scanner.nextLine();
            groupChatClient.sendInfo(str);
        }
    }
}

Bootstrap方法详解——技术与实例 一、Introduction 如果说到Bootstrap你会想到什么?是Twitter推出的那个用于前端开发的开源工具包吗?Unfortunately,本文要讨论的并非是Bootstrap工具包,而是统计学习中一种重采样(Resampling)技术。这种看似简单的方法,对后来的很多技术都产生了深远的影响。机器学习中的Bagging,AdaBoost等方法其实都蕴含了Bootstrap的思想... 阅读详情

相关推荐

人工智能AI在软件测试和质量效能中的实际应用

人工智能在软件测试中应用,介绍chatGPT在测试中的应用,还有多个AI驱动的测试工具。

lindafang72的博客 1万+

netty搭建web聊天室(2)群聊

上节课完成了netty的后端搭建,搞定了简单的http请求响应,今天来结合前端websocket来完成群聊功能。话不多说先上图: 前端构建 不使用复杂构建工具直接静态页面走起 使用了zui样式库 http://zui.sexy/?#/,非常不错,有好多模板。我使用的是聊天模板改造 <link rel="stylesheet...

weixin_34102807的博客 291

BES2810_best1702_best1702_ibrt_三者关系深度解析

一颗芯片的三个名字:BES2810、best1702 与 best1702_ibrt 关系深度解析

weixin_42162924的博客 349

Netty实现群聊系统

1 需求 (1) 编写一个 Netty群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) (2) 实现多人群聊 (3) 服务器端:可以监测用户上线,离线,并实现消息转发功能 (4) 客户端:通过 channel可以无阻塞发送消息给其它所有用户,同时可以接受其它用 (5) 户发送的消息(有服务器转发得到) 目的:进一步理解Net非阻塞网络编程机制 2 Code 2.1 GroupChatConsts public final class GroupChatConsts { private G

qq_34125999的博客 2116

自定义模型训练——打造专属OpenClaw模型(2026AI版)

本文介绍了OpenClaw自定义模型训练的核心流程,包括框架选择(PyTorch、TensorFlow、HuggingFace和原生OpenClaw框架)、训练环境搭建脚本、以及数据收集系统的设计。数据收集器支持从数据库、API、文件和网络等多种来源获取训练数据,并提供灵活的过滤机制确保数据质量。通过这套系统,开发者可以高效准备训练数据,为后续模型训练打下坚实基础。

博客 875

matlab之作图设置游标的精度

matlab画出的figure游标的精度往往是固定的,这就对我们的调试和查看数据造成了不便。 那么怎么修改游标的精度呢? 首先,获取游标dcm_obj = datacursormode(gcf);然后对游标的精度进行设置:set(dcm_obj,'UpdateFcn',@NewCallback)这个NewCallback是什么东西呢?这是一个可以返回游标精度的函数,具体内容如下:function

落日之城 8957

Netty-使用netty实现群聊-代码实现

使用Netty实现一个简单的群聊功能

CodeDabaicai的博客 552

【报错解决】OpenClaw 报错 Unsupported engine: requires node >=22.0.0 —— Node.js 版本过低的完整排查与解决实录

在国产操作系统环境下部署OpenClaw时遇到"Unsupported engine: requires node >=22.0.0"报错,分析表明该工具要求Node.js 22+以支持fetch API等新特性。解决方案包括:1) 使用nvm升级Node至22+版本;2) Docker环境中改用node:22-alpine镜像;3) 不推荐强制忽略引擎检查。文章强调遵循引擎要求的重要性,指出环境版本是工程化体系稳定运行的关键,建议通过规范升级解决兼容性问题。(149字)

博客 607

基于Netty实现群聊功能

有你的日子你就是一切,没你的日子一切都是你 又是一天新的开始,让我来带领你打开任督二脉。。。 前言: 在前面有了对NIO、BIO知识的学习,以及对netty结构组的基本了解,接下来将学习一下如何使用netty去实现一个群聊功能,读者可自行去对比基于NIO、BIO、Netty实现群聊功能的不同方式,以更深刻的理解IO网络编程。 学习内容: 整体思路: 1) 编写一个Netty群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 2) 实现多人聊天 3) 服务器端:可以监测用户上线,离线,并实现消息.

收破烂的小熊猫 781

借助ChatGPT完成课题申报书中框架思路写作指南

通过这篇文章的学习,我们可以让ChatGPT先为用户匹配研究理论、研究方法、研究思路、研究内容等,为申请人提供一些参考,能够帮助对拟申报课题有一个初步的认识。当申请人找到了合适的理论、方法和问题后,再借助精细化提示词模型提问,那ChatGPT回答的启发性肯定会有质的提升,更具有使用价值。

智能AI让学术科研更容易 2468

2024年12月数据月报

2024年12月大数据月报,为您准备了阿里、字节、百度等大厂150多篇实践案例

SmartSi 2654

Netty 入门实战之实现简易聊天系统

Netty 是什么?用官方文档来说,Netty 是一个高性能、异步事件驱动的网络应用框架。基于 Netty,可以快速地开发和部署高性能、高可用的网络服务端和客户端应用。 简单来说,Netty 是一个封装了 Java NIO 的 Jar 包,是对 Socket 网络编程的封装。Netty 应用广泛,一些知名框架 Alibaba Dubbo、Apache Flink、Apache Spark、gRP...

Geek_ymv的专栏 558

面向红外小目标检测的SCTransNet:模型优势解析、代码实现与完整复现指南

摘要:本文详细介绍了基于SCTransNet的红外小目标检测全流程实践方案。针对红外小目标检测面临的三大挑战(特征稀缺、背景干扰、尺度变化),SCTransNet通过空-通道交叉注意力机制有效增强目标特征。文章包含完整的PyTorch实现代码,涵盖特征提取、注意力模块、多尺度融合等核心组件,并提供模型训练、评估的具体方法。同时给出毕设创新方向的建议,如模型轻量化、多模态融合等,帮助提升研究深度。该方案技术难度适中,应用价值明确,是红外目标检测领域理想的毕设选题方向。

m0_71589036的博客 4759

[Netty] 基于NIO的简单群聊系统

介绍 基于Netty的后端群聊系统,实现的功能有 监听客户端的上线和下线、 监听客户端的消息的发送 代码 服务端 package com.gxd.nio.groupchat; import jdk.nashorn.internal.ir.annotations.Ignore; import org.omg.CORBA.IRObject; import java.io.IOException; import java.net.InetSocketAddress; import java.net.So

GxDong_的博客 223

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Netty入门-第二话

文章目录Netty 概述原生 NIO 存在的问题Netty 官网说明Netty 的优点Netty 版本说明Netty 高性能架构设计线程模型基本介绍传统阻塞 I/O 服务模型工作原理图模型特点问题分析Reactor 模式针对传统阻塞 I/O 服务模型的 2 个缺点,解决方案:I/O 复用结合线程池,就是 Reactor 模式基本设计思想,如图Reactor 模式中核心组成Reactor 模式分类单 Reactor 单线程方案说明方案优缺点分析单 Reactor 多线程方案说明方案优缺点分析主从 Reacto

youthlql的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Netty学习——实战篇2 NIO 群聊系统(简单版)

log.info("用户,{}",socketChannel.getRemoteAddress(),"已上线");log.info("来自客户端:{}, 的消息是:{}",socketChannel.getRemoteAddress(),msg);log.info("{}",socketChannel.getRemoteAddress(),":已下线");//log.info("用户:{},说:{}",username,message);log.info("{},客户端初始化完成",username);

geminigoth的博客 1383

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Netty剖析之NIO群聊系统

前言 在前面我们详细讲解了BIO、NIO,本次我们将使用NIO来完成一个群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞); 群聊系统基本要求: 服务器端可监测客户端上线、离线、并转发客户端消息; 客户端可群发消息给其它用户,也可接收其它客户发送的消息; 代码示例 服务端: public class GroupChatServer { private Selector sel...

皓晨的架构笔记 329

4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)

你好,我是彤哥,本篇是netty系列的第四篇。 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识。 简介 上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使用纯纯的NIO实现一个越聊越上瘾的“群聊系统”。 业务逻辑分析 首先,我们先来分析一下群聊的功能点: (1)加入群聊,并通知其他人; (2)发言,并通知其他人; (3)退出群聊,并通知其他人; 一个简单的群...

彤哥读源码 1243

Netty+WebSocket打造实时群聊系统:原理+代码

Netty 是一个。

2301_78566776的博客 1362

Netty学习笔记 3.10 NIO 网络编程应用实例-群聊系统

Netty学习笔记 3.10 NIO 网络编程应用实例-群聊系统 实例要求: 编写一个 NIO 群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 实现多人群聊 服务器端:可以监测用户上线,离线,并实现消息转发功能 客户端:通过channel 可以无阻塞发送消息给其它所有用户,同时可以接受其它用户发送的消息(有服务器转发得到) 目的:进一步理解NIO非阻塞网络编程机制 Server 端 服务器接收到消息 时间: [2019-09-29 12:02:35] -> 服务器 ok… 1

zyzy123321的博客 3490

4.基于NIO的群聊系统

本文总结自B站《netty-尚硅谷》,很不错;

PacosonSWJTU的博客 641

基于NIO的群聊系统简单实现

实例要求: (1)编写一个NIO多人群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) (2)服务器端:可以监测用户上线、离线,并实现消息转发功能 (3)客户端:通过channel可以无阻塞发送消息给其它所有用户,同时可以接受其它用户发送的消息(都是由服务器转发得到) (4)目的:进一步理解NIO非阻塞网络编程机制 服务器 package nio.groupchat; import ...

以后我要当村长 265

一起来学Netty吧——NIO简单实现群聊

基于NIO实现群聊系统 先来简单阐述一下思路: 服务器端 package netty.GroupChat; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; import java.util.Set; /** * @ClassName GroupChatServ

少歌的博客 253

(四)Netty基础Nio的群聊系统

NIO群聊系统 熟悉NIO三大组件核心API实现一个简单的群聊系统,不同用户可以收到非自身用户发的消息。 主要熟悉Api Selector SeletorKeys Channel selectedKeys()返回所有发生期望事件的key channel()返回channel write(ByteBuffer) 将buffer数据写入chanel keys()获取所有绑定到selector上的key 常用的状态常量 read(ByteBuffer)从buffer中数据读到channel中

woshiwjma956的博客 261

分别用BIO、NIO、Netty实现的简单聊天室系统

这是一个没有用数据库的只用网络和多线程实现的基于控制台输入输出的聊天室系统,不过我想加了数据库的思路也应该差不多吧,在这里,服务端的作用就是将一个客户端发送的数据转给其他客户端看,还有就是注意私聊的处理的就行了; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; i...

中都 1732

尚硅谷2019年Netty教程 NIO 群聊系统 ----目标netty---step4.01

https://www.bilibili.com/video/BV1jK4y1s7GV?p=29 https://www.bilibili.com/video/BV1jK4y1s7GV?p=30 https://www.bilibili.com/video/BV1jK4y1s7GV?p=31 https://www.bilibili.com/video/BV1jK4y1s7GV?p=32 尚硅谷2019年Netty教程 NIO 群聊系统 一共分为4讲 29,30 ----server端编码 31,32 --

狗剩的专栏 385
上一篇: Netty-NIO学习-基于FileChannel读写实战
下一篇: Netty-通过Maven构建Netty项目-IDEA依赖导入
酱油瓶啤酒杯
博客等级 码龄8年 35粉丝 135原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值