当前位置: 首页 > news >正文

SpringBoot项目监听端口接受数据(Netty版)

文章目录

  • 前言
  • 服务端
    • 相关配置
    • 核心代码
  • 客户端


前言

前言
环境:
JDK:64位 Jdk1.8
SpringBoot:2.1.7.RELEASE
Netty:4.1.39.Final

功能:
使用Netty监听端口接受客户端的数据,并发送数据给客户端。

服务端

相关配置

pom.xml

        <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.39.Final</version></dependency>

application.yml

netty-socket:port: 9992bufferSize: 2048

配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** @author qf* @since 2024/10/08 21:08*/
@Component
@ConfigurationProperties(prefix = "netty-socket")
@Data
public class SocketConfig {private Integer port;private Integer bufferSize;
}

核心代码

CommandLineRunner
当应用程序启动时,CommandLineRunner 接口的实现类中的 run 方法会被调用

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;/*** @author qf* @since 2024/10/08 21:11*/
@Slf4j
@Component
public class CommandLineRunnerImpl implements CommandLineRunner {@Autowiredprivate NettyServer nettyServer;@Overridepublic void run(String... args) throws Exception {log.info("-----------监听端口启动成功!-----------");nettyServer.start(); // 启动Netty服务}
}

服务类

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author qf* @since 2024/10/08 21:13*/
@Slf4j
@Component
public class NettyServer {@Autowiredprivate SocketConfig socketConfig;public void start() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();try {Integer bufferSize = socketConfig.getBufferSize();ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(bufferSize, bufferSize, bufferSize)).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {//\n和\r\n分隔符ch.pipeline().addLast(new LineBasedFrameDecoder(bufferSize));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new StringEncoder());// 添加自定义的业务处理器ch.pipeline().addLast(new DeviceServerHandler());}});ChannelFuture channelFuture = bootstrap.bind(socketConfig.getPort()).sync();log.info("启动TCP服务器启动成功,正在监听端口:{}", socketConfig.getPort());channelFuture.channel().closeFuture().sync();} catch (Exception e) {log.info("netty发生错误:", e);} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}

业务处理器

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;/*** @author qf* @since 2024/10/08 21:15*/
@Slf4j
public class DeviceServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String dateStr) throws Exception {// 处理接收到的消息// 你可以在这里添加更复杂的业务逻辑,比如解析消息、访问数据库等。log.info("'监听的数据为'------->:" + dateStr);if (true) {//发送数据给客户端ctx.writeAndFlush("hello~");}}}

客户端

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;import java.net.InetSocketAddress;/*** @author qf* @since 2024/10/11 18:01*/
public class HelloClient {public static void main(String[] args) throws InterruptedException {// 1. 启动类,启动客户端new Bootstrap()// 2. 添加 EventLoop.group(new NioEventLoopGroup())//如果服务器端发来数据,客户端的EventLoop就可以从selector触发读事件进行处理// 3. 选择客户端 channel 实现,底层封装了SocketChannel.channel(NioSocketChannel.class)// 4. 添加处理器.handler(new ChannelInitializer<NioSocketChannel>() {@Override // 在连接建立后被调用protected void initChannel(NioSocketChannel ch) throws Exception {ch.pipeline().addLast(new StringEncoder());//编码器,将字符串编码成ByteBuf进行发送ch.pipeline().addLast(new EchoClientHandler());}})// 5. 连接到服务器.connect(new InetSocketAddress("localhost", 9992)).sync()//sync()是一个阻塞方法,只有连接建立后才会继续执行.channel()//.channel()表示拿到服务器和客户端之间的SocketChannel(连接对象)// 6. 向服务器发送数据.writeAndFlush("hello, world\n");}
}
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;/*** @author qf* @since 2024/10/11 18:05*/
public class EchoClientHandler extends ChannelInboundHandlerAdapter {private final ByteBuf message;public EchoClientHandler() {message = Unpooled.buffer(256);message.writeBytes("hello netty".getBytes(CharsetUtil.UTF_8));}@Overridepublic void channelActive(ChannelHandlerContext ctx) {ctx.writeAndFlush(message);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {String data = ((ByteBuf) msg).toString(CharsetUtil.UTF_8);System.out.println(data);
//        ctx.write(msg);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// Close the connection when an exception is raised.cause.printStackTrace();ctx.close();}
}

相关文章:
SpringBoot项目监听端口接受数据(NIO版)

相关文章:

SpringBoot项目监听端口接受数据(Netty版)

文章目录 前言服务端相关配置核心代码 客户端 前言 前言 环境&#xff1a; JDK&#xff1a;64位 Jdk1.8 SpringBoot&#xff1a;2.1.7.RELEASE Netty&#xff1a;4.1.39.Final 功能&#xff1a; 使用Netty监听端口接受客户端的数据&#xff0c;并发送数据给客户端。 服务端 …...

超标量处理器设计笔记(9) 重命名映射表、超标量处理器重命名中相关性问题

寄存器重命名 重命名映射表基于 SRAM 的重命名映射表 超标量处理器的寄存器重命名解决 RAW 相关性解决 WAW 相关性对写 RAT 进行检查&#xff08;判断哪个 ARF 写入到 RAT&#xff09;对写 ROB 进行检查&#xff08;判断&#xff09; 特殊指令处理方式 重命名映射表 重命名时…...

如何使用 Python 写入文本文件 ?

在Python编程中&#xff0c;写入文本文件是一项基本且重要的操作。 无论是生成日志文件、配置文件&#xff0c;还是进行数据输出&#xff0c;都需要用到这一技能。 下面&#xff0c;我将详细介绍如何使用Python写入文本文件&#xff0c;并提供一些实际开发中的建议和注意事项…...

07篇(附)--仿射变换矩阵

此篇献给某些 头铁 的小只因们&#xff0c;认真钻研下面的数学式吧 原理示例 首先我们以最简单的一个点的旋转为例子&#xff0c;且以最简单的情况举例&#xff0c;令旋转中心为坐标系中心O&#xff08;0&#xff0c;0&#xff09;&#xff0c;假设有一点P0(x0,y0)&#xff0…...

KubeSphere搭建单节点RocketMQ

前提环境: Docker环境 Harbor仓库(可选) 参考官方文档: 《Docker 部署 RocketMQ》 https://rocketmq.apache.org/zh/docs/quickStart/02quickstartWithDocker参考官方文档: 《RocketMQ Dashboard》 https://rocketmq.apache.org/zh/docs/deploymentOperations/04Dashboard/ 声…...

深度学习中损失函数(loss function)介绍

深度学习中损失函数(loss function)介绍 ​ 在深度学习的宏伟城堡中&#xff0c;损失函数扮演着国王的角色&#xff0c;它决定了模型训练的方向和目标。损失函数&#xff0c;也被称为代价函数&#xff0c;是衡量模型预测与实际结果之间差异的函数。在深度学习的训练过程中&…...

Vue3+Node中使用webrtc推流至mediamtx

前言 项目的 Web 端是 Vue3 框架&#xff0c;后端是 GO 框架。需要实现将客户端的本地摄像头媒体流推送至服务端&#xff0c;而我自己从未有媒体流相关经验&#xff0c;最初 leader 让我尝试通过 RTSP 协议推拉流&#xff0c;我的思路就局限在了 RTSP 方向。 最初使用的服务端…...

React 内置的Hook学习

useState&#xff1a;管理组件状态 useState 是一个用于在函数组件中添加状态的 Hook。它允许你在函数组件中声明一个状态变量&#xff0c;并提供一个更新该状态的方法&#xff0c;其中与组件生命周期的关系&#xff1a; 初始化&#xff1a;当组件首次渲染时&#xff0c;useS…...

Flutter Navigator2.0的原理和Web端实践

01 背景与动机 在Navigator 2.0推出之前&#xff0c;Flutter主要通过Navigator 1.0和其提供的 API&#xff08;如push(), pop(), pushNamed()等&#xff09;来管理页面路由。然而&#xff0c;Navigator 1.0存在一些局限性&#xff0c;如难以实现复杂的页面操作&#xff08;如移…...

初次使用uniapp编译到微信小程序编辑器页面空白,真机预览有内容

uniapp微信小程序页面结构 首页页面代码 微信小程序模拟器 模拟器页面为空白时查了下&#xff0c;有几个说是“Hbuilder编译的时候应该编译出来一个app.js文件 但是却编译出了App.js”&#xff0c;但是我的小程序结构没问题&#xff0c;并且真机预览没有问题 真机调试 根据defi…...

【HF设计模式】03-装饰者模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第3章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍装饰者模式&#xff0c;包括遇到的问题、遵循的 OO 原则、达到的效果。 …...

【人工智能-中级】模型部署与优化:从本地实验到云端与边缘部署

模型部署与优化:从本地实验到云端与边缘部署 在机器学习和深度学习模型训练完成后,如何高效、稳定地将模型部署到生产环境中,是实际应用中的关键环节。模型部署不仅涉及技术实现,还需要考虑性能优化、资源管理和安全性等多方面因素。本文将全面探讨模型部署与优化的相关内…...

Jenkins 编写Pipeline 简介及使用初识详解

一、Jenkins Pipeline简介 Jenkins Pipeline是Jenkins的一个重要功能,Jenkins 2.0 以上才会有,一系列 Jenkins 插件将整个持续集成用解释性代码 Jenkinsfile 来描述,它允许开发者以代码的方式定义整个持续集成和交付(CI/CD)流程,包括构建、测试、部署和监控等步骤。Jenk…...

uboot移植网络驱动过程,无法ping通mx6ull和ubuntu问题解决方案

开发板&#xff1a;mx6ull-ALPHA_V2.4 ubuntu版本&#xff1a;20.04 1.现在虚拟机设置中添加网路适配器用于开启桥接模式 2.在编辑中打开“虚拟网络编辑器” 我的电脑本身只有VMnet1和VMnet8&#xff0c;需要底下“添加网络”&#xff0c;增加这个VMnet0 &#xff0c;并且进行…...

精准预测美国失业率和贫困率,谷歌人口动态基础模型PDFM已开源,可增强现有地理空间模型

疾病、经济危机、失业、灾害……人类世界长期以来被各种各样的问题「侵扰」&#xff0c;了解人口动态对于解决这类复杂的社会问题至关重要。 政府相关人员可以通过人口动态数据来模拟疾病的传播&#xff0c;预测房价和失业率&#xff0c;甚至预测经济危机。然而&#xff0c;在过…...

C#速成(文件读、写操作)

导包 using System.IO;1、写入文件&#xff08;重要&#xff09; StreamWriter sw new StreamWriter("C:\Users\29674\Desktop\volumn.txt");//创建一个TXT的文件 sw.WriteLine(textBox2.Text);//写入文件的内容 sw.Close();//关闭2、读取文件&#xff08;不重要&…...

SQL server学习03-创建和管理数据表

目录 一&#xff0c;SQL server的数据类型 1&#xff0c;基本数据类型 2&#xff0c;自定义数据类型 二&#xff0c;使用T-SQL创建表 1&#xff0c;数据完整性的分类 2&#xff0c;约束的类型 3&#xff0c;创建表时创建约束 4&#xff0c;任务 5&#xff0c;由任务编写…...

【UE5 “RuntimeLoadFbx”插件】运行时加载FBX模型

前言 为了解决在Runtime时能够直接根据FBX模型路径直接加载FBX的问题&#xff0c;推荐一款名为“RuntimeLoadFBX”的插件。 用法 插件用法如下&#xff0c;只需要指定fbx的地址就可以在场景中生成Actor模型 通过指定输入参数“Cal Collision”来设置FBX模型的碰撞 还可以通过…...

【潜意识Java】深入理解 Java 面向对象编程(OOP)

目录 什么是面向对象编程&#xff08;OOP&#xff09;&#xff1f; 1. 封装&#xff08;Encapsulation&#xff09; Java 中的封装 2. 继承&#xff08;Inheritance&#xff09; Java 中的继承 3. 多态&#xff08;Polymorphism&#xff09; Java 中的多态 4. 抽象&…...

windows同时使用多个网卡

windows同时链接了有线网络,多个无线网卡,默认会使用有线网络,如果想要局域网内使用某个特定的网络,可以设置静态ip 1. 首先删除原来的静态网络(不冲突可以不删除),我这里usb无线网卡切换过usb插口,这里需要删除原来的. 使用 route print 查看接口列表及静态路由信息 route p…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...