ROS学习笔记11(用C++写一个简单的消息发布和消息订阅)

ROS总结——ROS消息发布和订阅 消息发布器和订阅器 (C++)本博客总结绍如何用 C++ 编写消息发布器节点和订阅器节点。1.编写发布器节点 节点(Node) 是指 ROS 网络中可执行文件。接下来,将会创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息。切换到之前创建的 beginner_tutorials package 路径:$ cd ~/catkin_ws/src/beginner_tutor 阅读详情

1 写一个消息发布节点

首先切换到工作目录:

roscd beginner_tutorials

接着,创建src/talker.cpp,代码如下:

/*
 * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
// %Tag(FULLTEXT)%
// %Tag(ROS_HEADER)%
#include "ros/ros.h"
// %EndTag(ROS_HEADER)%
// %Tag(MSG_HEADER)%
#include "std_msgs/String.h"
// %EndTag(MSG_HEADER)%

#include <sstream>

/**
 * This tutorial demonstrates simple sending of messages over the ROS system.
 */
int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line.
   * For programmatic remappings you can use a different version of init() which takes
   * remappings directly, but for most command-line programs, passing argc and argv is
   * the easiest way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
// %Tag(INIT)%
  ros::init(argc, argv, "talker");
// %EndTag(INIT)%

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
// %Tag(NODEHANDLE)%
  ros::NodeHandle n;
// %EndTag(NODEHANDLE)%

  /**
   * The advertise() function is how you tell ROS that you want to
   * publish on a given topic name. This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing. After this advertise() call is made, the master
   * node will notify anyone who is trying to subscribe to this topic name,
   * and they will in turn negotiate a peer-to-peer connection with this
   * node.  advertise() returns a Publisher object which allows you to
   * publish messages on that topic through a call to publish().  Once
   * all copies of the returned Publisher object are destroyed, the topic
   * will be automatically unadvertised.
   *
   * The second parameter to advertise() is the size of the message queue
   * used for publishing messages.  If messages are published more quickly
   * than we can send them, the number here specifies how many messages to
   * buffer up before throwing some away.
   */
// %Tag(PUBLISHER)%
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
// %EndTag(PUBLISHER)%

// %Tag(LOOP_RATE)%
  ros::Rate loop_rate(10);
// %EndTag(LOOP_RATE)%

  /**
   * A count of how many messages we have sent. This is used to create
   * a unique string for each message.
   */
// %Tag(ROS_OK)%
  int count = 0;
  while (ros::ok())
  {
// %EndTag(ROS_OK)%
    /**
     * This is a message object. You stuff it with data, and then publish it.
     */
// %Tag(FILL_MESSAGE)%
    std_msgs::String msg;

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();
// %EndTag(FILL_MESSAGE)%

// %Tag(ROSCONSOLE)%
    ROS_INFO("%s", msg.data.c_str());
// %EndTag(ROSCONSOLE)%

    /**
     * The publish() function is how you send messages. The parameter
     * is the message object. The type of this object must agree with the type
     * given as a template parameter to the advertise<>() call, as was done
     * in the constructor above.
     */
// %Tag(PUBLISH)%
    chatter_pub.publish(msg);
// %EndTag(PUBLISH)%

// %Tag(SPINONCE)%
    ros::spinOnce();
// %EndTag(SPINONCE)%

// %Tag(RATE_SLEEP)%
    loop_rate.sleep();
// %EndTag(RATE_SLEEP)%
    ++count;
  }


  return 0;
}
// %EndTag(FULLTEXT)%

2 写一个消息订阅节点

创建一个src/listener.cpp,输入以下

/*
 * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

// %Tag(FULLTEXT)%
#include "ros/ros.h"
#include "std_msgs/String.h"

/**
 * This tutorial demonstrates simple receipt of messages over the ROS system.
 */
// %Tag(CALLBACK)%
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}
// %EndTag(CALLBACK)%

int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line.
   * For programmatic remappings you can use a different version of init() which takes
   * remappings directly, but for most command-line programs, passing argc and argv is
   * the easiest way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  ros::init(argc, argv, "listener");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle n;

  /**
   * The subscribe() call is how you tell ROS that you want to receive messages
   * on a given topic.  This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing.  Messages are passed to a callback function, here
   * called chatterCallback.  subscribe() returns a Subscriber object that you
   * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
   * object go out of scope, this callback will automatically be unsubscribed from
   * this topic.
   *
   * The second parameter to the subscribe() function is the size of the message
   * queue.  If messages are arriving faster than they are being processed, this
   * is the number of messages that will be buffered up before beginning to throw
   * away the oldest ones.
   */
// %Tag(SUBSCRIBER)%
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
// %EndTag(SUBSCRIBER)%

  /**
   * ros::spin() will enter a loop, pumping callbacks.  With this version, all
   * callbacks will be called from within this thread (the main one).  ros::spin()
   * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
   */
// %Tag(SPIN)%
  ros::spin();
// %EndTag(SPIN)%

  return 0;
}
// %EndTag(FULLTEXT)%

3 构建节点

在CMakeLists.txt最后添加:

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

完整文件:

   1 cmake_minimum_required(VERSION 2.8.3)
   2 project(beginner_tutorials)
   3 
   4 ## Find catkin and any catkin packages
   5 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)
   6 
   7 ## Declare ROS messages and services
   8 add_message_files(FILES Num.msg)
   9 add_service_files(FILES AddTwoInts.srv)
  10 
  11 ## Generate added messages and services
  12 generate_messages(DEPENDENCIES std_msgs)
  13 
  14 ## Declare a catkin package
  15 catkin_package()
  16 
  17 ## Build talker and listener
  18 include_directories(include ${catkin_INCLUDE_DIRS})
  19 
  20 add_executable(talker src/talker.cpp)
  21 target_link_libraries(talker ${catkin_LIBRARIES})
  22 add_dependencies(talker beginner_tutorials_generate_messages_cpp)
  23 
  24 add_executable(listener src/listener.cpp)
  25 target_link_libraries(listener ${catkin_LIBRARIES})
  26 add_dependencies(listener beginner_tutorials_generate_messages_cpp)


ref:http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber(c%2B%2B)

我的ROS入门(五):总算搞通ROS的服务节点订阅发布消息话题了 总算搞通ROS的服务节点订阅发布消息主题了。可以实习那几个东西。 记录一下吧,首先要一个工作空间。 在当前系统用户的home目录下的.bashrc文件中添加source /opt/ros/jade/setup.bash,才能运行ros相关的命令。 开始创建一个catkin工作空间 $ mkdir -p ~/catkin_lljws/src $ cd ~/catkin_lljws/src 阅读详情

相关推荐

ROS手动编写消息发布器和订阅器topic demo(C++)

1.首先创建 packagecd ~/catkin_ws/srccatkin_create_pkg topic_demo roscpp rospy std_msgs2. 编写 msg 文件cd topic_demomkdir msgcd msgvim gps.msg将以下代码写入:float32 x float32 y string statex 是横坐标,y 是纵坐标,state 是状态还记得以...

Nikki_o3o的博客 5051

ROS话题通信实现发布接收以及vscode编译配置(五)C++版本

[rosrun] Couldn't find executable named demo01_pub below /home/david/demo03_ws/src/plumbing_pub_sub 如果出现了这个报错那么应该是上面编译没选对 要选catkin_make:build这个编译任务然后要对应修改其json文件 #include "ros/ros.h" 导入包的时候显示报错先不用管,这是因为没有编译导致的

weixin_50920579的博客 3057

ROS发布/订阅Float64MultiArray数组类消息(C++和Python相互发布和订阅)

再次领略了ROS系统一个很好的特性,能兼容不同语言的节点,只要规范好发布信息的类型是匹配的,就能让不同语言编写的节点互相通信。 Target: 想让python写的node发布数组,而让C++写的node订阅这个发布的数据。 Method: 1.Python发布,C++订阅 1)先选择发布消息的类型,选定为Float64MultiArray 2)然后是python节点的代码: #!/usr/bin/env python # encoding: utf-8 # Echo client program im

Will_Ye的博客 1万+

Ros自定义消息话题通信代码(C++实现)

【代码】Ros自定义消息话题通信代码(C++实现)

qq_44701348的博客 678

ROS 的通信机制之话题订阅模型详解

话题订阅模型在ROS中的实现本质上依赖于底层的通信机制和网络编程。

weixin_46999174的博客 3441

创建ROS消息发布器(publisher)、订阅器(subscriber)

发布器和订阅器都是可执行文件。对C++语言,我们在.cpp文件中创建,并编译生成可执行文件, 发布器: 1、cd到包目录下,然后在src文件夹下创建.cpp文件; 2、.cpp文件包括以下部分:      ①包含(include)依赖库,如ros/ros.h、std_msgs/String.h、sstream等      ②主函数部分:  ros::init(argc,argv,

DjangoBUAA的博客 2760

C++发布订阅模式

发布订阅模式

youaremyalllove的博客 3287

ros c++ 简单教程

ros c++ 简单教程–刘田 文章目录ros c++ 简单教程--刘田cmake怎么写?catkin怎么用?• 新建一个ros_package• cmake中catkin怎么写?c++中ros 常用语法• c++中ros头文件怎么写?C++ 基本节点订阅发布的关键函数?• 发布函数和接受函数的简单示例• 发布函数• 接受函数• 类的方法实现订阅发布ros 中的服务怎么用?三种基本服务类型是什么?...

三川小哥 狂想曲 4641

ros学习11--Writing Publisher Subscriber(c++) (编写简单的发布者和订阅者(C++))

本文ubuntu20.04+ros1,是初学者按照官网初级教程学习记录,仅作个人学习记录,如有问题可联系本文作者。附上ros1官网链接ros2官网链接。

m0_60030502的博客 397

基于C++11模板实现的发布/订阅开发框架读取《雪中悍刀行》

基于C++11模板实现的发布/订阅开发框架读取《雪中悍刀行》

Hermes+MemOS记忆系统:用SQLite构建可编辑AI个人认知资产

AI记忆不是简单延长上下文或叠加RAG,而是构建具备分层存储、混合检索与自然语言反馈能力的个人认知资产。其核心原理在于将用户交互痕迹(L1)、偏好策略(L2)、结构化世界模型(L3)和结晶化技能统一管理,实现记忆的可追溯、可修正、可进化。技术价值体现在降低token消耗、提升长程一致性、支持离线演进,并突破传统‘静态快照’式知识库局限。典型应用场景包括个人知识助手、客服工单分析Agent、研发文档理解系统等。本文聚焦Hermes Agent与MemOS深度集成方案,详解SQLite作为ACID底座支撑L1/

weixin_33623304的博客 434

C++11 新特性:多執行序程式開發 Thread

http://kheresy.wordpress.com/2012/07/06/multi-thread-programming-in-c-thread-p1/ http://kheresy.wordpress.com/2012/07/06/multi-thread-programming-in-c-thread-p2/ http://kheresy.wordpress.com/2012/

头顶篮球的摇滚程序员 790

ScanNet数据集详解

ScanNet 是一个 RGB-D 视频数据集,在超过 1500 次扫描中包含了 250 万个视图,并标注了 3D 相机位姿、表面重建和实例级的语义分割。为了收集这些数据,设计了一个易于使用且具有扩展性的 RGB-D 捕获系统,包括自动化的表面重建和众包的语义标注。如果您想下载 ScanNet 数据,请使用您的机构邮箱地址填写一份 ScanNet 使用条款协议,并发送至 scannet@googlegroups.com。压缩包是将3D的标注信息“拍扁”成2D图片的结果,对应原始视频的每一帧。

frostmelody 全网同名,大家多多关注呀~ 持续分享优质内容! 3921

ROS学习笔记(二)ROS消息发布(publish)与订阅(subscribe)(C++代码详解)

ROS消息发布与订阅实践及C++代码详解

直撞三千 2万+

扬声器设计避坑指南:用Comsol分析反电动势对THD的影响(附案例文件)

本文深入探讨了扬声器设计中反电动势对总谐波失真的关键影响。通过COMSOL仿真,详细分析了BL值非线性、音圈电感变化等电磁-力-声耦合机制,并提供了从参数化建模到系统级优化的实战指南,帮助工程师精准量化并降低谐波失真,提升扬声器音质。

xx56789的博客 521

多雷达协同探测技术研究进展:认知跟踪与资源调度算法

源自:雷达学报作者:易伟 袁野 刘光宏 葛建军 孔令讲 杨建宇雷达是信息感知的千里眼,具有极高的军用和民用价值,广泛应用在防空预警、遥感测绘、反恐维稳等领域[1–5]。雷达信息获取与探测技术也一直是大国竞相抢占的前沿技术,同时是信息科学的重要组成部分。随着科学技术不断进步,先进电子对抗装备的不断问世和广泛列装,雷达的生存与发展正面临日益严峻的挑战。从生存环境上看,雷达面临通信等各类民用电磁干扰以及复杂的军用电磁干扰;从探测对象上看,集群、微弱、隐身、高空、低空等多样化目标的出现也给雷达探测与识别带来困难。

renhongxia1的博客 2784

ROS2学习笔记之C++编写简单发布订阅节点篇

ROS2学习笔记之C++编写简单发布订阅节点篇背景前期准备学习内容1. 为例程创建一个包2. 编写publisher发布者节点2.1 代码解释2.2 添加依赖2.3 CMakeLists.txt3. 编写subscriber订阅者节点4. 编译节点并运行总结 学习目标:用C++创建并且运行订阅发布的简单节点 背景 节点是一个通过ROS网络进行数据交互的可执行文件的进程。在这篇教程当中,我们编写一个...

dckwin的博客 1万+

【AI技术赋能有限元分析应用实践】Abaqus有限元分析与深度学习结合20个案例与有限元分析数据来源方法说明

结合 Abaqus 和深度学习,数据的获取和处理是关键的一步。通过从仿真、实验、公开数据库或合成数据中获取数据,经过预处理后,可以将其用于训练深度学习模型。最终,将训练好的深度学习模型与 Abaqus 集成,用于材料行为预测、结构优化、非线性分析、损伤预测等任务,从而提升仿真效率和精度。

源代码杀手的博客 3213

ROS学习笔记(一)补充篇 参考创客制造

我吧ROS的CPP部分分成7个部分: 1、基础的node param 2、动态调节参数 3、关于TF变换 4、actionlib 5、插件技术 6、movebase 7、nodelet技术前言相比于ros学习笔记一,ros学习笔记一补充篇将会更加注重代码的讲解。ros学习笔记一只是像大观园一样,看看ROS这个领域的山山水水。而ros学习笔记一补充篇将会深入的补充这些山山水水的来源节点n

DavidHan008 1万+

智能Agent如何重塑企业流程

在当今数字化时代,企业流程的效率和敏捷性至关重要。传统企业流程往往受限于人工操作,效率低下、成本高昂,难以适应快速变化的市场环境。智能Agent作为一种新兴技术,凭借其强大的智能化能力,正在逐渐改变企业流程的运作模式,为企业带来新的机遇和挑战。智能Agent是一种能够感知环境、自主决策、执行任务的软件实体。它可以模拟人类的智能行为,例如学习、推理、规划和沟通。通过将智能Agent嵌入到企业流程中,可以实现流程的自动化、优化和智能化,从而提高效率、降低成本、提升客户体验。8.1 研究成果总结。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 874

openGauss学习笔记-280 openGauss性能调优-实际调优案例09-修改启动参数解决TPCC大幅度波动

openGauss学习笔记-280 openGauss性能调优-实际调优案例09-修改启动参数解决TPCC大幅度波动280.1 现象描述280.2 优化分析 openGauss学习笔记-280 ope

超哥的博客 309

深入了解ROS细节之编写简单的消息发布器和订阅器 (C++)、mavros消息发布器和订阅器

深入了解ROS细节之消息发布器和订阅器、mavros消息发布器和订阅器 编写简单的消息发布器和订阅器 (C++) 编写发布器节点 『节点』(Node) 是指 ROS 网络中可执行文件。接下来,我们将会创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息、切换到之前创建的 beginner_tutorials package 路径下: cd ~/catkin_ws/src...

习惯积淀的博客 963

“软开关”硬技术!ZVS和ZCS到底谁更牛?看完这个例子你就懂了!

❌ ZVS 和 ZCS 是万能的?→ 不,它们都有实现条件,谐振参数选不好照样硬拐弯!❌ 只要有谐振就一定ZVS?→ 不,一定要设计合适的死区时间和负载条件才行!ZVS 是让电压先“冷静”,ZCS 是让电流先“退场”。一个是开门不撞墙,一个是关门不甩门。懂了它们,功率设计就是在跳华尔兹而不是打架!💃🔌。

weixin_43199439的博客 1239

ROS发布和订阅数组消息/ C++ & Python

ROS发布和订阅数组消息/ C++ & PythonROS发布和订阅数组消息一个发布数组消息的talker节点(C++)一个订阅数组消息的节点(Python) ROS发布和订阅数组消息 前段时间需要用到C++来写节点发布数组消息,并用Python来订阅该消息,在网上搜索发现关于数组消息的帖子少之又少,遂把自己做的一点微小的工作发上来,欢迎指正. 一个发布数组消息的talker节点(C++)...

zxx258369的博客 5529

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ROS学习笔记-ROS订阅和发布节点

一个简单的ROS包,一个发布者,一个订阅者 刚开始学习ROS,参考网上的资料完成了测试节点的编写,记录一下。 个人习惯在home/Develop目录中做开发,于是在Develop目录下面创建了一个ROS目录,专门用作ROS开发 1,创建工作空间 在自己的ROS目录(随便一个目录即可)下面新建一个工程目录demo,在demo目录下面创建一个工作空间 创建相关目录 cd /home/Develop/...

qq_29022265的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ROS实现消息发布器和订阅器——Hello Word

维基百科ROS官方教程cn/ROS/Tutorials - ROS Wiki 通过节点间定义话题,实现ROS消息和服务通信

Yangy_Jiaojiao的博客 4051

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: ROS学习笔记6(理解ROS话题)
下一篇: ROS学习笔记12(用Python写一个简单的消息发布和消息订阅)
刘凯KAI
博客等级 码龄15年 663粉丝 128原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值