Netty传输object并解决粘包拆包问题

news2024/10/7 4:29:19

⭐️ 前言

大家好,笔者之前写过一篇文章,《Netty中粘包拆包问题解决探讨》,就Netty粘包拆包问题及其解决方案进行了探讨,本文算是这篇博客的延续。探讨netty传输object的问题。

在这里插入图片描述

本文将netty结合java序列化来传输object并解决粘包拆包问题,虽然netty已经提供了ObjectEncoder和ObjectDecoder来完成此任务,但本文想把这个功能简单化,来拆解其中的原理。

⭐️ java序列化

java序列化相关的资料很多,这里就不再赘述,show the code!!!

⭐️ netty传输object

这里客户端发送了三条消息(对象实例),在最后一条消息发送时进行flush操作。

Trade类定义了我们要传输的对象,其中除了一般实体类应该具备的元素外,按ddd领域模型设计的思想,还封装了两个业务方法:toByteArray和fromByteArray,来方便Trade对象与字节数组的转换。

public class Trade implements Serializable {

    private int id;

    private String name;

    private float payment;

    private Date maturity;

    public Trade() {}

    public Trade(int id, String name, float payment, Date maturity) {
        this.id = id;
        this.name = name;
        this.payment = payment;
        this.maturity = maturity;
    }

    public String toString(){
        return String.format("id: %d, name: %s, payment: %f, maturity: %s", id, name, payment,
                new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(maturity));
    }

    /***
     * 对象序列化为字节数组
     * @return
     * @throws IOException
     */
    public byte[] toByteArray() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        byte[] data;
        try {
            oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            data = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                oos.close();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
        return data;
    }

    /***
     * 从字节数组中读取对象
     * @param bytes
     * @return
     */
    public static Trade fromByteArray(byte[] bytes) {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(bais);
            return (Trade) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                ois.close();
                bais.close();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPayment() {
        return payment;
    }

    public void setPayment(float payment) {
        this.payment = payment;
    }

    public Date getMaturity() {
        return maturity;
    }

    public void setMaturity(Date maturity) {
        this.maturity = maturity;
    }
}

ServerTestHandler用以处理并显示客户端发给服务端的数据

public class ServerTestHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        // 消息(传输的对象)长度
        int len = buf.readInt();
        System.out.println(String.format("消息(传输的对象)长度:%s", len));
        // 接收对象内容的字节数组
        byte[] arr = new byte[len];
        // 将对象读到字节数组中
        buf.readBytes(arr);
        // 从字节数组中解析Trade对象
        Trade tr = Trade.fromByteArray(arr);
        System.out.println("来自client的消息:" + tr.toString());
    }
}

需要注意的是,在再给server设置Handler时,LengthFieldBasedFrameDecoder中的参数initialBytesToStrip要设置为0,因为我们用LengthFieldBasedFrameDecoder对Frame进行界定的同时,还要在ServerTestHandler读取对象的长度。

server端代码

public class Server {
        public static void main(String[] args) {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .childOption(ChannelOption.SO_KEEPALIVE, true)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            protected void initChannel(SocketChannel socketChannel) throws Exception {
                                ChannelPipeline pipeline = socketChannel.pipeline();
                                pipeline.addLast(new LoggingHandler())
                                        .addLast(new LengthFieldBasedFrameDecoder(1024,0, 4, 0, 0))
                                        .addLast(new ServerTestHandler());
                            }
                        });
                System.out.println("server ready");
                ChannelFuture sync = bootstrap.bind(8888).sync();
                sync.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
}

client端代码

public class Client {
    public static void main(String[] args) {
        EventLoopGroup workGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.group(workGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new LoggingHandler())
                                    .addLast(new LengthFieldPrepender(4));
                        }
                    });
            System.out.println("client ok");
            ChannelFuture localhost = bootstrap.connect("localhost", 8888).sync();
            // 发送消息
            Calendar instance = Calendar.getInstance();
            instance.set(2023, 11, 11, 10, 10, 5);
            Trade trade1 = new Trade(1, "trade1", 1.5f, instance.getTime());
            byte[] trade1Bytes = trade1.toByteArray();
            localhost.channel().write(Unpooled.copiedBuffer(trade1Bytes));

            instance.set(2023, 10, 20, 9, 8, 5);
            Trade trade2 = new Trade(2, "trade2", 0.5f, instance.getTime());
            byte[] trade2Bytes = trade2.toByteArray();
            localhost.channel().write(Unpooled.copiedBuffer(trade2Bytes));

            instance.set(2023, 4, 11, 13, 13, 45);
            Trade trade3 = new Trade(3, "trade3", 7.1f, instance.getTime());
            byte[] trade3Bytes = trade3.toByteArray();
            localhost.channel().writeAndFlush(Unpooled.copiedBuffer(trade3Bytes));

            localhost.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            workGroup.shutdownGracefully();
        }
    }
}

client端日志

         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 b1                                     |....            |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,096 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] WRITE: 177B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| ac ed 00 05 73 72 00 18 63 6f 6d 2e 78 68 63 2e |....sr..com.xhc.|
|00000010| 6e 65 74 2e 65 6e 74 69 74 79 2e 54 72 61 64 65 |net.entity.Trade|
|00000020| 99 8e 9b 76 ff dc b3 1f 02 00 04 49 00 02 69 64 |...v.......I..id|
|00000030| 46 00 07 70 61 79 6d 65 6e 74 4c 00 08 6d 61 74 |F..paymentL..mat|
|00000040| 75 72 69 74 79 74 00 10 4c 6a 61 76 61 2f 75 74 |urityt..Ljava/ut|
|00000050| 69 6c 2f 44 61 74 65 3b 4c 00 04 6e 61 6d 65 74 |il/Date;L..namet|
|00000060| 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 |..Ljava/lang/Str|
|00000070| 69 6e 67 3b 78 70 00 00 00 01 3f c0 00 00 73 72 |ing;xp....?...sr|
|00000080| 00 0e 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 |..java.util.Date|
|00000090| 68 6a 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 |hj..KYt....xpw..|
|000000a0| 00 01 8c 56 a3 80 74 78 74 00 06 74 72 61 64 65 |...V..txt..trade|
|000000b0| 31                                              |1               |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,098 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] WRITE: 4B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 b1                                     |....            |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,098 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] WRITE: 177B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| ac ed 00 05 73 72 00 18 63 6f 6d 2e 78 68 63 2e |....sr..com.xhc.|
|00000010| 6e 65 74 2e 65 6e 74 69 74 79 2e 54 72 61 64 65 |net.entity.Trade|
|00000020| 99 8e 9b 76 ff dc b3 1f 02 00 04 49 00 02 69 64 |...v.......I..id|
|00000030| 46 00 07 70 61 79 6d 65 6e 74 4c 00 08 6d 61 74 |F..paymentL..mat|
|00000040| 75 72 69 74 79 74 00 10 4c 6a 61 76 61 2f 75 74 |urityt..Ljava/ut|
|00000050| 69 6c 2f 44 61 74 65 3b 4c 00 04 6e 61 6d 65 74 |il/Date;L..namet|
|00000060| 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 |..Ljava/lang/Str|
|00000070| 69 6e 67 3b 78 70 00 00 00 02 3f 00 00 00 73 72 |ing;xp....?...sr|
|00000080| 00 0e 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 |..java.util.Date|
|00000090| 68 6a 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 |hj..KYt....xpw..|
|000000a0| 00 01 8b ea 45 31 34 78 74 00 06 74 72 61 64 65 |....E14xt..trade|
|000000b0| 32                                              |2               |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,098 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] WRITE: 4B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 b1                                     |....            |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,099 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] WRITE: 177B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| ac ed 00 05 73 72 00 18 63 6f 6d 2e 78 68 63 2e |....sr..com.xhc.|
|00000010| 6e 65 74 2e 65 6e 74 69 74 79 2e 54 72 61 64 65 |net.entity.Trade|
|00000020| 99 8e 9b 76 ff dc b3 1f 02 00 04 49 00 02 69 64 |...v.......I..id|
|00000030| 46 00 07 70 61 79 6d 65 6e 74 4c 00 08 6d 61 74 |F..paymentL..mat|
|00000040| 75 72 69 74 79 74 00 10 4c 6a 61 76 61 2f 75 74 |urityt..Ljava/ut|
|00000050| 69 6c 2f 44 61 74 65 3b 4c 00 04 6e 61 6d 65 74 |il/Date;L..namet|
|00000060| 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 |..Ljava/lang/Str|
|00000070| 69 6e 67 3b 78 70 00 00 00 03 40 e3 33 33 73 72 |ing;xp....@.33sr|
|00000080| 00 0e 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 |..java.util.Date|
|00000090| 68 6a 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 |hj..KYt....xpw..|
|000000a0| 00 01 88 09 3a bf 54 78 74 00 06 74 72 61 64 65 |....:.Txt..trade|
|000000b0| 33                                              |3               |
+--------+-------------------------------------------------+----------------+
2023/11/17 18:12:15,099 [DEBUG]AbstractInternalLogger-[id: 0xd71e6e91, L:/127.0.0.1:53675 - R:localhost/127.0.0.1:8888] FLUSH

server端日志

         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 b1 ac ed 00 05 73 72 00 18 63 6f 6d 2e |........sr..com.|
|00000010| 78 68 63 2e 6e 65 74 2e 65 6e 74 69 74 79 2e 54 |xhc.net.entity.T|
|00000020| 72 61 64 65 99 8e 9b 76 ff dc b3 1f 02 00 04 49 |rade...v.......I|
|00000030| 00 02 69 64 46 00 07 70 61 79 6d 65 6e 74 4c 00 |..idF..paymentL.|
|00000040| 08 6d 61 74 75 72 69 74 79 74 00 10 4c 6a 61 76 |.maturityt..Ljav|
|00000050| 61 2f 75 74 69 6c 2f 44 61 74 65 3b 4c 00 04 6e |a/util/Date;L..n|
|00000060| 61 6d 65 74 00 12 4c 6a 61 76 61 2f 6c 61 6e 67 |amet..Ljava/lang|
|00000070| 2f 53 74 72 69 6e 67 3b 78 70 00 00 00 01 3f c0 |/String;xp....?.|
|00000080| 00 00 73 72 00 0e 6a 61 76 61 2e 75 74 69 6c 2e |..sr..java.util.|
|00000090| 44 61 74 65 68 6a 81 01 4b 59 74 19 03 00 00 78 |Datehj..KYt....x|
|000000a0| 70 77 08 00 00 01 8c 56 a3 80 74 78 74 00 06 74 |pw.....V..txt..t|
|000000b0| 72 61 64 65 31 00 00 00 b1 ac ed 00 05 73 72 00 |rade1........sr.|
|000000c0| 18 63 6f 6d 2e 78 68 63 2e 6e 65 74 2e 65 6e 74 |.com.xhc.net.ent|
|000000d0| 69 74 79 2e 54 72 61 64 65 99 8e 9b 76 ff dc b3 |ity.Trade...v...|
|000000e0| 1f 02 00 04 49 00 02 69 64 46 00 07 70 61 79 6d |....I..idF..paym|
|000000f0| 65 6e 74 4c 00 08 6d 61 74 75 72 69 74 79 74 00 |entL..maturityt.|
|00000100| 10 4c 6a 61 76 61 2f 75 74 69 6c 2f 44 61 74 65 |.Ljava/util/Date|
|00000110| 3b 4c 00 04 6e 61 6d 65 74 00 12 4c 6a 61 76 61 |;L..namet..Ljava|
|00000120| 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 78 70 00 |/lang/String;xp.|
|00000130| 00 00 02 3f 00 00 00 73 72 00 0e 6a 61 76 61 2e |...?...sr..java.|
|00000140| 75 74 69 6c 2e 44 61 74 65 68 6a 81 01 4b 59 74 |util.Datehj..KYt|
|00000150| 19 03 00 00 78 70 77 08 00 00 01 8b ea 45 31 34 |....xpw......E14|
|00000160| 78 74 00 06 74 72 61 64 65 32 00 00 00 b1 ac ed |xt..trade2......|
|00000170| 00 05 73 72 00 18 63 6f 6d 2e 78 68 63 2e 6e 65 |..sr..com.xhc.ne|
|00000180| 74 2e 65 6e 74 69 74 79 2e 54 72 61 64 65 99 8e |t.entity.Trade..|
|00000190| 9b 76 ff dc b3 1f 02 00 04 49 00 02 69 64 46 00 |.v.......I..idF.|
|000001a0| 07 70 61 79 6d 65 6e 74 4c 00 08 6d 61 74 75 72 |.paymentL..matur|
|000001b0| 69 74 79 74 00 10 4c 6a 61 76 61 2f 75 74 69 6c |ityt..Ljava/util|
|000001c0| 2f 44 61 74 65 3b 4c 00 04 6e 61 6d 65 74 00 12 |/Date;L..namet..|
|000001d0| 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e |Ljava/lang/Strin|
|000001e0| 67 3b 78 70 00 00 00 03 40 e3 33 33 73 72 00 0e |g;xp....@.33sr..|
|000001f0| 6a 61 76 61 2e 75 74 69 6c 2e 44 61 74 65 68 6a |java.util.Datehj|
|00000200| 81 01 4b 59 74 19 03 00 00 78 70 77 08 00 00 01 |..KYt....xpw....|
|00000210| 88 09 3a bf 54 78 74 00 06 74 72 61 64 65 33    |..:.Txt..trade3 |
+--------+-------------------------------------------------+----------------+
消息(传输的对象)长度:177
来自client的消息:id: 1, name: trade1, payment: 1.500000, maturity: 2023-12-11 10:10:05
消息(传输的对象)长度:177
来自client的消息:id: 2, name: trade2, payment: 0.500000, maturity: 2023-11-20 09:08:05
消息(传输的对象)长度:177
来自client的消息:id: 3, name: trade3, payment: 7.100000, maturity: 2023-05-11 01:13:45
2023/11/17 18:12:15,143 [DEBUG]AbstractInternalLogger-[id: 0x143e8152, L:/127.0.0.1:8888 - R:/127.0.0.1:53675] READ COMPLETE

可以看到,三个对象成功的被服务器接收并正确的解析了。

笔者水平有限,若有不对的地方欢迎评论指正!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言——求1/1-1/2+1/3-......+1/99-1/100的值

#include<stdio.h> int main() {int i 1;double sum 0;int flage 1;for(i 1;i < 100; i){sumflage*1.0/i;flage -flage; //正负号}printf("%lf\n",sum);return 0; }

2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-B

2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-B 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略设置 A-3 流量完整性保护 A-4 …

二十一、数组(1)

本章概要 数组特性 用于显示数组的实用程序 一等对象返回数组 简单来看&#xff0c;数组需要你去创建和初始化&#xff0c;你可以通过下标对数组元素进行访问&#xff0c;数组的大小不会改变。大多数时候你只需要知道这些&#xff0c;但有时候你必须在数组上进行更复杂的操作…

Ubuntu18.04安装Moveit框架

简介 Moveit是一个由一系列移动操作的功能包组成的集成化开发平台,提供友好的GUI,是目前ROS社区中使用度排名前三的功能包,Moveit包含以下三大核心功能,并集成了大量的优秀算法接口: 运动学:KDL,Trac-IK,IKFast...路径规划:OMPL,CHMOP,SBPL..碰撞检测:FCL,PCD... 一、更新功…

前段-用面向对象的方式开发一个水管小鸟的游戏

首先准备好各类空文件 index.js css html 和图片 图片是下面这些&#xff0c;如果没有的可在这里下载 2 开发开始 好了&#xff0c;基础准备工作完毕&#xff0c;开发开始&#xff0c; 首先&#xff0c;先把天空&#xff0c;大地&#xff0c;小鸟的盒子准备好&#xff0c;并…

基于探路者算法优化概率神经网络PNN的分类预测 - 附代码

基于探路者算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于探路者算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于探路者优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

main函数的数组参数是干嘛用的

今天在看项目代码的时候&#xff0c;突然看到项目中用到了main函数的参数args&#xff0c;在这之前我还没怎么注意过这个参数&#xff0c;一时间居然不知道这个参数是干嘛的&#xff01; 虽然也写过一些java和scala&#xff0c;但是确实没遇到过会用这个参数的情况。 网上就查…

【PIE-Engine 数据资源】中国叶面积指数(LAI)月度合成产品

文章目录 一、 简介二、描述三、波段四、示例代码运行结果参考资料 一、 简介 数据名称中国叶面积指数&#xff08;LAI&#xff09;月度合成产品时间范围2002-2021年空间范围全国数据来源航天宏图代码片段var images pie.ImageCollection(“EMDO/MODIS_MONTH_LAI_CHINA”) 二…

Arduino项目式编程教学前言

前言–先聊聊我的经历 在停更数年之后&#xff0c;还是打算重新开启Arduino编程教学这一项目&#xff1b;这几年间&#xff0c;我从Arduino编程开发教学&#xff0c;转到C及python教学&#xff0c;又到如今的高中数学教学&#xff0c;跨度竟如此之大&#xff0c;但始终未脱离教…

echarts 三角锥形柱状图 + 带阴影的折线图示例

该示例有如下几个特点&#xff1a; ①三角锥形折线图 ②折线图自带阴影 ③三角锥形鼠标放置时颜色改变 ④数据随着鼠标移动而展示 ⑤鼠标放置时tooltip样式自定义&#xff08;echarts 实现tooltip提示框样式自定义-CSDN博客&#xff09; 代码如下&#xff1a; this.options …

【GUI】-- 08 JButton、JRadioButton、JCheckBox

GUI编程 03 Swing 3.5 JButton 图片置于按钮之上的JButton&#xff1a; package com.duo.lesson05;import javax.swing.*; import java.awt.*; import java.net.URL;public class JButtonDemo01 extends JFrame {public JButtonDemo01() {Container contentPane getConten…

opencv(4):颜色空间

文章目录 颜色空间RGB 人眼的色彩空间HSV 色彩空间HSLYUVYUV420&#xff1a;YUV422&#xff1a;YUV444&#xff1a; 颜色空间转换代码示例 颜色空间 不同色彩空间显示效果是不一样的。 RGB 人眼的色彩空间 HSV 色彩空间 HSV 代表色相&#xff08;Hue&#xff09;、饱和度&a…

YOLO改进系列之注意力机制(EffectiveSE模型介绍)

模型结构 ESE(Effective Squeeze and Extraction) layer是CenterMask模型中的一个block&#xff0c;基于SE&#xff08;Squeeze and Extraction&#xff09;改进得到。与SE的区别在于&#xff0c;ESE block只有一个fc层&#xff0c;(CenterMask : Real-Time Anchor-Free Insta…

2019年12月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 以下程序执行后,角色面向的方向是? A:右上 B:右下 C:左上 D:左下 答案:B 面向-135度,是面向左下角,向右旋转-90度等于向左旋转90度。所以会旋转到右下角。 第2题 以下程…

WordPress网站迁移实战经验

前几日,网站服务器到期,换了服务商,就把我的WordPress的网站迁移到本地电脑了。方便以后文章迁移。 本次迁移网站主要经历以下几个步骤。 1.域名转出。 2.备份数据库及网站文件下载。 3.重新搭建WordPress网站。 4.网站文件及数据库导入。 下面详细介绍下每个步骤的操作…

基于STC12C5A60S2系列1T 8051单片的IIC总线器件数模芯片PCF8591实现数模转换应用

基于STC12C5A60S2系列1T 8051单片的IIC总线器件数模芯片PCF8591实现数模转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍IIC总线器件数模芯片PCF8591介绍通过按…

RabbitMQ 安装及配置

前言 当你准备构建一个分布式系统、微服务架构或者需要处理大量异步消息的应用程序时&#xff0c;消息队列就成为了一个不可或缺的组件。而RabbitMQ作为一个功能强大的开源消息代理软件&#xff0c;提供了可靠的消息传递机制和灵活的集成能力&#xff0c;因此备受开发人员和系…

CMakeLists.txt基础指令与cmake-gui生成VS项目的步骤

简介 本博客主要介绍cmake的基本指令&#xff0c;同时&#xff0c;很多使用Visual Studio小白从Gitbub下载项目源码后&#xff0c;看到CMakeLists.txt&#xff0c;不知道如何使用Visual Studio编译源码&#xff1b;针对以上问题&#xff0c;做一下简单操作与解释&#xff0c;方…

各类好玩免费API推荐,早知道就不用到处爬数据了...

啥是API/接口&#xff1f; 使用方法 API平台 淘宝/京东API接口数据 一些好玩的api 地图接口 天气查询接口 快递查询接口 笔记接口 其它接口 小结 啥是API/接口&#xff1f; 有些读者刚开始学习编程遇到API或者接口不太明白到底什么意思&#xff0c;没关系&#xff0…

Java项目实战《苍穹外卖》 一、项目概述

人道洛阳花似锦&#xff0c;偏我来时不逢春。 系列文章目录 苍穹外卖是黑马程序员2023年的Java实战项目&#xff0c;作为业余练手用&#xff0c;需要源码或者课程的可以找我&#xff0c;无偿分享 Java项目实战《苍穹外卖》 一、项目概述Java项目实战《苍穹外卖》 二、项目搭建 …