3.netty和protobuf
1.ChannelGroup可以免遍历由netty提供,覆盖remove方法即可触发删除channel\
2.群聊私聊
13.群聊私聊简单原理图
3.netty心跳检测机制,客户端对服务器有没有读写(读,写空闲)
//IdleStateHandler(3,5,7,TimeUnite.SECONDS)是netty提供的检测状态的处理器,也加到pipeline,读,写,读写都没有
//并在handler类实现方法userEventTriggered处理事件
@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if(evt instanceof IdleStateEvent) {//将 evt 向下转型 IdleStateEventIdleStateEvent event = (IdleStateEvent) evt;String eventType = null;switch (event.state()) {case READER_IDLE:eventType = "读空闲";break;case WRITER_IDLE:eventType = "写空闲";break;case ALL_IDLE:eventType = "读写空闲";break;}System.out.println(ctx.channel().remoteAddress() + "--超时时间--" + eventType);System.out.println("服务器做相应处理..");//如果发生空闲,我们关闭通道// ctx.channel().close();}}//init注意的顺序pipeline.addLast("MyHttpServerCodec",new HttpServerCodec());
- 增加一个自定义的handler
pipeline.addLast(new IdleStateHandler(7000,7000,10, TimeUnit.SECONDS));
pipeline.addLast("MyTestHttpServerHandler", new TestHttpServerHandler());
4.websocker实现全双工(两边可以通信,半双工只能一边通信)的长连接,
//因为大数据时http会发送多次请求获取数据,所以要升级用ws协议
//html有WebSocket对象,发送http请求然后200状态码转为101为ws协议
public class MyServer {public static void main(String[] args) throws Exception{//创建两个线程组EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup(); //8个NioEventLooptry {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup);serverBootstrap.channel(NioServerSocketChannel.class);serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//相当于链式编程//因为基于http协议,使用http的编码和解码器pipeline.addLast(new HttpServerCodec());//是以块方式写,添加ChunkedWriteHandler处理器pipeline.addLast(new ChunkedWriteHandler());/*说明1. http数据在传输过程中是分段, HttpObjectAggregator ,就是可以将多个段聚合2. 这就就是为什么,当浏览器发送大量数据时,就会发出多次http请求*/pipeline.addLast(new HttpObjectAggregator(8192));/*说明1. 对应websocket ,它的数据是以 帧(frame) 形式传递2. 可以看到WebSocketFrame 下面有六个子类3. 浏览器请求时 ws://localhost:7000/hello 表示请求的uri4. WebSocketServerProtocolHandler 核心功能是将 http协议升级为 ws协议 , 保持长连接5. 是通过一个 状态码 101*/pipeline.addLast(new WebSocketServerProtocolHandler("/hello2"));//自定义的handler ,处理业务逻辑pipeline.addLast(new MyTextWebSocketFrameHandler());}});//启动服务器ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();channelFuture.channel().closeFuture().sync();}finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}public class MyTextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {System.out.println("服务器收到消息 " + msg.text());//回复消息ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间" + LocalDateTime.now() + " " + msg.text()));}//当web客户端连接后, 触发方法@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {//id 表示唯一的值,LongText 是唯一的 ShortText 不是唯一System.out.println("handlerAdded 被调用" + ctx.channel().id().asLongText());System.out.println("handlerAdded 被调用" + ctx.channel().id().asShortText());}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {System.out.println("handlerRemoved 被调用" + ctx.channel().id().asLongText());}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println("异常发生 " + cause.getMessage());ctx.close(); //关闭连接}
}
5.编码(cli)—二进制–>解码(server)
1.netty提供的 StringEncoder ObjectEncoder
2.但是使用java底层序列化和反序列化效率低
3.无法跨语言,google protobuf可以解决 ,很多公司由http+json–>tcp+protobuf
6.protobuf (是RPC remote procedure call远程过程调用) 跨平台 生成的大对象包含多个小对象
1.引入依赖
2.写 xxx.proto文件,idea安装插件protobuf
pipeline.addLast("encoder", new ProtobufEncoder()); //netty需要加netty自带protobuf解编码器//普通的写法
syntax = "proto3";option java_outer_classname="StudentPOJO"; // 外部类名, 文件名message Student {int32 id = 1;//Student类的属性string name = 2; //
}//升级版//需要注意包名,要根据自己的项目包创建,没有可不指定//版本//生成外部类文件名 message Student{ enum DataType{ StudentType =0; //enum编号从0开始WorkType =1;}DataType data_type=1; //标识传入那个类型的id WorkType oneof dataBody{ //相当于在对象中选一个作为属性Student student =2; Worker worker =3;}} message Student{ //看文档,不要写java语言类型int32 id=1; //属性的序号string name=2;} message Work{ //看文档,不要写java语言类型int32 id=1; //属性的序号string name=2;}
3.打开下载好的 protoc.exe生成java文件
protoc.exe --java_out=. Student.proto //有空格隔开,生成到当前文件夹,输入Student.proto文件,文件名在配置文件中写
4.客户端
StudentPOJO.Student.new Builder.setId(4).setName("ss").build();//可以发送多种对象,而不是一个对象//添加编解码器if(0 == random) { //发送Student 对象myMessage = MyDataInfo.MyMessage.newBuilder().setDataType(MyDataInfo.MyMessage.DataType.StudentType).setStudent(MyDataInfo.Student.newBuilder().setId(5).setName("玉麒麟 卢俊义").build()).build();} else { // 发送一个Worker 对象myMessage = MyDataInfo.MyMessage.newBuilder().setDataType(MyDataInfo.MyMessage.DataType.WorkerType).setWorker(MyDataInfo.Worker.newBuilder().setAge(20).setName("老李").build()).build();}
//完整代码 StudentPOJO.proto
syntax = "proto3";
option optimize_for = SPEED; // 加快解析
option java_package="com.atguigu.netty.codec2"; //指定生成到哪个包下!!!
option java_outer_classname="MyDataInfo"; // 外部类名, 文件名//protobuf 可以使用message 管理其他的message
message MyMessage {//定义一个枚举类型enum DataType {//可以设置枚举类型,然后在java里面判断StudentType = 0; //在proto3 要求enum的编号从0开始WorkerType = 1;}//用data_type 来标识传的是哪一个枚举类型DataType data_type = 1;//表示每次枚举类型最多只能出现其中的一个, 节省空间,另外一个对象如果在java取值变为空值,oneof dataBody {Student student = 2;Worker worker = 3;}}message Student {int32 id = 1;//Student类的属性string name = 2; //
}
message Worker {string name=1;int32 age=2;
}
public class NettyServer {public static void main(String[] args) throws Exception {//创建BossGroup 和 WorkerGroup//说明//1. 创建两个线程组 bossGroup 和 workerGroup//2. bossGroup 只是处理连接请求 , 真正的和客户端业务处理,会交给 workerGroup完成//3. 两个都是无限循环//4. bossGroup 和 workerGroup 含有的子线程(NioEventLoop)的个数// 默认实际 cpu核数 * 2EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup(); //8try {//创建服务器端的启动对象,配置参数ServerBootstrap bootstrap = new ServerBootstrap();//使用链式编程来进行设置bootstrap.group(bossGroup, workerGroup) //设置两个线程组.channel(NioServerSocketChannel.class) //使用NioSocketChannel 作为服务器的通道实现.option(ChannelOption.SO_BACKLOG, 128) // 设置线程队列得到连接个数.childOption(ChannelOption.SO_KEEPALIVE, true) //设置保持活动连接状态
// .handler(null) // 该 handler对应 bossGroup , childHandler 对应 workerGroup.childHandler(new ChannelInitializer<SocketChannel>() {//创建一个通道初始化对象(匿名对象)//给pipeline 设置处理器@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//在pipeline加入ProtoBufDecoder//指定对哪种对象进行解码pipeline.addLast("decoder", new ProtobufDecoder(MyDataInfo.MyMessage.getDefaultInstance())); //!!!入站 解码.pipeline.addLast(new NettyServerHandler());}}); // 给我们的workerGroup 的 EventLoop 对应的管道设置处理器System.out.println(".....服务器 is ready...");//绑定一个端口并且同步, 生成了一个 ChannelFuture 对象//启动服务器(并绑定端口)ChannelFuture cf = bootstrap.bind(6668).sync();//给cf 注册监听器,监控我们关心的事件cf.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {if (cf.isSuccess()) {System.out.println("监听端口 6668 成功");} else {System.out.println("监听端口 6668 失败");}}});//对关闭通道进行监听cf.channel().closeFuture().sync();}finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}
//处理
public class NettyServerHandler extends SimpleChannelInboundHandler<MyDataInfo.MyMessage> {//读取数据实际(这里我们可以读取客户端发送的消息)/*1. ChannelHandlerContext ctx:上下文对象, 含有 管道pipeline , 通道channel, 地址2. Object msg: 就是客户端发送的数据 默认Object*/@Overridepublic void channelRead0(ChannelHandlerContext ctx, MyDataInfo.MyMessage msg) throws Exception {//根据dataType 来显示不同的信息MyDataInfo.MyMessage.DataType dataType = msg.getDataType();if(dataType == MyDataInfo.MyMessage.DataType.StudentType) {MyDataInfo.Student student = msg.getStudent();System.out.println("学生id=" + student.getId() + " 学生名字=" + student.getName());} else if(dataType == MyDataInfo.MyMessage.DataType.WorkerType) {MyDataInfo.Worker worker = msg.getWorker();System.out.println("工人的名字=" + worker.getName() + " 年龄=" + worker.getAge());} else {System.out.println("传输的类型不正确");}}// //读取数据实际(这里我们可以读取客户端发送的消息)
// /*
// 1. ChannelHandlerContext ctx:上下文对象, 含有 管道pipeline , 通道channel, 地址
// 2. Object msg: 就是客户端发送的数据 默认Object
// */
// @Override
// public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//
// //读取从客户端发送的StudentPojo.Student
//
// StudentPOJO.Student student = (StudentPOJO.Student) msg;
//
// System.out.println("客户端发送的数据 id=" + student.getId() + " 名字=" + student.getName());
// }//数据读取完毕@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//writeAndFlush 是 write + flush//将数据写入到缓存,并刷新//一般讲,我们对这个发送的数据进行编码ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端~(>^ω^<)喵1", CharsetUtil.UTF_8));}//处理异常, 一般是需要关闭通道@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
}
//客户端
public class NettyClient {public static void main(String[] args) throws Exception {//客户端需要一个事件循环组EventLoopGroup group = new NioEventLoopGroup();try {//创建客户端启动对象//注意客户端使用的不是 ServerBootstrap 而是 BootstrapBootstrap bootstrap = new Bootstrap();//设置相关参数bootstrap.group(group) //设置线程组.channel(NioSocketChannel.class) // 设置客户端通道的实现类(反射).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//在pipeline中加入 ProtoBufEncoderpipeline.addLast("encoder", new ProtobufEncoder()); //!!!入站编码二进制位java编码pipeline.addLast(new NettyClientHandler()); //加入自己的处理器}});System.out.println("客户端 ok..");//启动客户端去连接服务器端//关于 ChannelFuture 要分析,涉及到netty的异步模型ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();//给关闭通道进行监听channelFuture.channel().closeFuture().sync();}finally {group.shutdownGracefully();}}
}
4.入站(服务器数据向cli) 出站(cli->server)(整个过程在pipeline里面进行) (想象为一个管道入栈需要解码(二进制变为数据),出站需要需要编码[变成二进制])
5.netty处理沾包粘包问题(需要相互判断接收的字节数,不然都是按一个包来处理,而我们是需要分开处理小的包)
//但是分段的数据会被handler和decode重复处理
6.netty handler链 图14.handler链
//如果发送的数据,不是我要编码的就不处理,所以我们要注意传入数据和传出数据类型要一样
//客户端和服务端都写解码和编码
7.解码器 RaplayingDecoder处理界面不用判断是否有足够的数据
//但是不是所有ByteBuf操作都支持,会抛异常,速度会变慢(信息变碎片->分片太多)
8.其他解码器
1.LineBasedFrameDecoder 行尾使用 \n或者\r\n分隔符解析数据
2.DelimiterBasedFrameDecoder 自定义特殊字符进行分割
3.LengthFieldBasedFrameDecoder指定长度来识别包,解决沾包粘包问题
4.好用的对数据进行压缩ZlibDecoder
5.httpObjectDecoder
9.maven项目使用netty,整合Log4j
10.TCP粘包(关键在数据长度)(小的包通过算法合成大包,可能出现接收的大包不完整,部分小包位置的问题)
和拆包问题
1.netty解决,自己定义协议对象+解密编码器,接收者得到长度,才得到数据(在这里不用判断长度,因为用长度创建byte[]数组,长度错误就报错) //客户端连续发送数据,就有粘包问题
//协议对象
public class MessageProtocol {private int len; //关键private byte[] content;public int getLen() {return len;}public void setLen(int len) {this.len = len;}public byte[] getContent() {return content;}public void setContent(byte[] content) {this.content = content;}
}
//解码器和加密器,可以分别识别出先写入大小和内容,解决粘包拆包问题
public class MyMessageDecoder extends ReplayingDecoder<Void> {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {System.out.println("MyMessageDecoder decode 被调用");//需要将得到二进制字节码-> MessageProtocol 数据包(对象)int length = in.readInt();//!!!!!!!!!!!!!!!!!!!核心步骤,得到的数据长度,然后再创建byte数组接收byte[] content = new byte[length];in.readBytes(content);//封装成 MessageProtocol 对象,放入 out, 传递下一个handler业务处理MessageProtocol messageProtocol = new MessageProtocol();messageProtocol.setLen(length); //messageProtocol.setContent(content);out.add(messageProtocol);}
}
public class MyMessageEncoder extends MessageToByteEncoder<MessageProtocol> {@Overrideprotected void encode(ChannelHandlerContext ctx, MessageProtocol msg, ByteBuf out) throws Exception {System.out.println("MyMessageEncoder encode 方法被调用");out.writeInt(msg.getLen());out.writeBytes(msg.getContent());}
}
public class MyClientHandler extends SimpleChannelInboundHandler<MessageProtocol> {private int count;@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {//使用客户端发送10条数据 "今天天气冷,吃火锅" 编号for(int i = 0; i< 5; i++) {String mes = "今天天气冷,吃火锅";byte[] content = mes.getBytes(Charset.forName("utf-8"));int length = mes.getBytes(Charset.forName("utf-8")).length;//创建协议包对象MessageProtocol messageProtocol = new MessageProtocol();messageProtocol.setLen(length);messageProtocol.setContent(content);ctx.writeAndFlush(messageProtocol);}}// @Overrideprotected void channelRead0(ChannelHandlerContext ctx, MessageProtocol msg) throws Exception {int len = msg.getLen();byte[] content = msg.getContent();System.out.println("客户端接收到消息如下");System.out.println("长度=" + len);System.out.println("内容=" + new String(content, Charset.forName("utf-8")));System.out.println("客户端接收消息数量=" + (++this.count));}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println("异常消息=" + cause.getMessage());ctx.close();}
}//server
//处理业务的handler
public class MyServerHandler extends SimpleChannelInboundHandler<MessageProtocol>{private int count;@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {//cause.printStackTrace();ctx.close();}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, MessageProtocol msg) throws Exception {//接收到数据,并处理int len = msg.getLen();byte[] content = msg.getContent();System.out.println();System.out.println();System.out.println();System.out.println("服务器接收到信息如下");System.out.println("长度=" + len);System.out.println("内容=" + new String(content, Charset.forName("utf-8")));System.out.println("服务器接收到消息包数量=" + (++this.count));//回复消息String responseContent = UUID.randomUUID().toString();int responseLen = responseContent.getBytes("utf-8").length;byte[] responseContent2 = responseContent.getBytes("utf-8");//构建一个协议包MessageProtocol messageProtocol = new MessageProtocol();messageProtocol.setLen(responseLen);messageProtocol.setContent(responseContent2);//向所有channel发送数据ctx.writeAndFlush(messageProtocol);}
}
相关文章:

3.netty和protobuf
1.ChannelGroup可以免遍历由netty提供,覆盖remove方法即可触发删除channel\ 2.群聊私聊 13.群聊私聊简单原理图 3.netty心跳检测机制,客户端对服务器有没有读写(读,写空闲) //IdleStateHandler(3,5,7,TimeUnite.SECONDS)是netty提供的检测状态的处理器,也加到pipeline,读,写,…...
NLP实践——Llama-2 多轮对话prompt构建
NLP实践——Llama-2 多轮对话prompt构建 1. 问题提出2. prompt的正确形式3. 效果测试4. 结尾 1. 问题提出 最近,META开源了Llama-2模型,受到了广泛的关注和好评,然而,在官方给的使用说明中,并没有对使用方法进行特别细…...

《TCP IP网络编程》第十四章
第 14 章 多播与广播 14.1 多播 多播(Multicast)方式的数据传输是基于 UDP 完成的。因此 ,与 UDP 服务器端/客户端的实现方式非常接近。区别在于,UDP 数据传输以单一目标进行,而多播数据同时传递到加入(注…...

网络基础-认识每层的设备和每层的特点用途
目录 网络层次常见设备各层介绍数据链路层网络层传输层应用层 网络层次 常见设备 各层介绍 数据链路层 有了MAC地址。数据链路层工作在局域网中的,以帧为单位进行传输和处理数据。 网络层 网络层有了IP。不同的网络通过路由器连接成为互联网 路由器的功能: …...
【Linux操作系统】深入解析Linux定时任务调度机制-cronat指令
在Linux操作系统中,定时任务调度是一项重要的功能,它可以让用户在指定的时间或周期性地执行特定的任务。这种机制使得用户能够自动化地执行一些重复性工作,提高工作效率。本文将详细介绍Linux定时任务调度的原理、常用指令和代码示例…...

动手学深度学习(一)预备知识
目录 一、数据操作 1. N维数组样例 2. 访问元素 3. 基础函数 (1) 创建一个行向量 (2)通过张量的shape属性来访问张量的形状和元素总数 (3)reshape()函数 (4)创建全0、全1、…...

item_get-KS-获取商品详情
一、接口参数说明: item_get-根据ID取商品详情 ,点击更多API调试,请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/ks/item_get 名称类型必须描述keyString是调用key(http://o0b.cn/…...
[华为OD] 最小传输时延(dijkstra算法)
明天就要面试了我也太紧张了吧 但是终于找到了一个比较好理解的dijkstra的python解法,让我快点把它背下来!!!! 文章目录 题目dijkstra算法的python实现python解答dfs解法dijkstra解法 题目 先把题目放出来 某通信网络…...

问道管理:总资产大于总市值好吗?
在财政领域,总财物和总市值是两个非常重要的指标。总财物是指公司所有的财物,包括固定财物、流动财物、无形财物等,而总市值则是指公司股票在商场上的总价值。当总财物大于总市值时,这是否是一个好的信号呢?咱们将从多…...

IBM Spectrum LSF (“LSF“ ,简称为负载共享设施) 用户案例
IBM Spectrum LSF (“LSF” ,简称为负载共享设施) 用户案例 IBM Spectrum LSF (“LSF” ,简称为负载共享设施) 软件是业界领先的企业级软件。 LSF 在现有异构 IT 资源之间分配工作,以创建共享,可扩展且容错的基础架构,…...

Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)
系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…...

Gis入门,使用起止点和两个控制点生成三阶贝塞尔曲线(共四个控制点,线段转曲线)
前言 本章讲解如何在gis地图中使用起止点和两个控制点(总共四个控制点)生成三阶贝塞尔曲线。 二阶贝塞尔曲线请参考上一章《Gis入门,如何根据起止点和一个控制点计算二阶贝塞尔曲线(共三个控制点)》 贝塞尔曲线(Bezier curve)介绍 贝塞尔曲线(Bezier curve)是一种…...

Web-7-深入理解Cookie与Session:实现用户跟踪和数据存储
深入理解Cookie与Session:实现用户跟踪和数据存储 今日目标 1.掌握客户端会话跟踪技术Cookie 2.掌握服务端会话跟踪技术Sesssion 1.会话跟踪技术介绍 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断…...
Springboot设置Https
1、修改配置文件application.yml,并将*.jks放到resource目录下。 server:port: 8080ssl:key-store: classpath:*.jkskey-store-password: *key-store-type: JKSenabled: truekey-alias: boe.com.cn2、添加http转https的配置 Configuration public class TomcatCon…...

Windows 使用 Linux 子系统,轻轻松松安装多个linux
Windows Subsystem for Linux WSL 简称WSL,是一个在Windows 10\11上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,其目标是使纯正的Ubuntu、Debian等映像能下载和解压到用户的本地计算机&#…...

中级课程——弱口令(认证崩溃)
文章目录 什么是弱口令密码生成器分类暴力破解万能密码测试环境工具 什么是弱口令 密码生成器 分类 暴力破解 万能密码 or true --测试环境 工具 九头蛇,超级弱口令爆破工具,bp,...

web自动化测试进阶篇05 ——— 界面交互场景测试
😏作者简介:博主是一位测试管理者,同时也是一名对外企业兼职讲师。 📡主页地址:【Austin_zhai】 🙆目的与景愿:旨在于能帮助更多的测试行业人员提升软硬技能,分享行业相关最新信息。…...

NICE-SLAM: Neural Implicit Scalable Encoding for SLAM论文阅读
论文信息 标题:NICE-SLAM: Neural Implicit Scalable Encoding for SLAM 作者:Zihan Zhu, Songyou Peng,Viktor Larsson — Zhejiang University 来源:CVPR 代码:https://pengsongyou.github.io/nice-slam…...

cmake 配置Visual studio的调试命令
配置代码如截图: set_property(TARGET ${TARGET_NAME} PROPERTY VS_DEBUGGER_COMMAND "./consoleTest.exe") set_property(TARGET ${TARGET_NAME} PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS "./config/labelDriver.cfg") set_propert…...

MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression--论文学习笔记
超越GIoU/DIoU/CIoU/EIoU MPDIoU让YOLOv7和YOLACT双双涨点 目标检测上的指标对比: 论文地址: [2307.07662] MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression (arxiv.org) 摘要 边界框回归(Bounding Box Regression&am…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...