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

[C++]C++实现本地TCP通讯的示例代码

这篇文章主要为大家详细介绍了C++如何利用TCP技术,实现本地ROS1和ROS2的通讯,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

  • 概要
  • 服务端代码
    • 头文件
    • 源代码
  • 客户端代码

概要

利用TCP技术,实现本地ROS1和ROS2的通讯。

服务端代码

头文件

 

#include <ros/ros.h>
#include "std_msgs/String.h"
#include "std_msgs/Bool.h"
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "geometry_msgs/Twist.h"using namespace std;class TCPPublisher
{public:TCPPublisher();~TCPPublisher();void cmdVelCallback(const geometry_msgs::Twist::ConstPtr& msg);private:ros::NodeHandle n, nPrivate;ros::Publisher tcpPub;ros::Subscriber cmdVelSub;// 创建服务器套接字int serverSocket;// 设置服务器地址结构sockaddr_in serverAddr;int clientSocket;std::string topicStatus;
};

源代码

#include "./tcp_pub/tcp_pub.h"TCPPublisher::TCPPublisher():nPrivate("~")
{nPrivate.param("topicStatus", topicStatus, std::string("/cmd_vel"));/*订阅话题*/cmdVelSub = n.subscribe(topicStatus.c_str(), 10, &TCPPublisher::cmdVelCallback, this);serverSocket = socket(AF_INET, SOCK_STREAM, 0);// 设置服务器地址结构sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(8080); // 服务器监听的端口号// 绑定套接字if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {std::cerr << "Bind failed." << std::endl;close(serverSocket);return;}// 监听连接if (listen(serverSocket, SOMAXCONN) == -1) {std::cerr << "Listen failed." << std::endl;close(serverSocket);return;}std::cout << "Server is listening for incoming connections..." << std::endl;ROS_INFO("TCPPublisher init successfully!!!");
}TCPPublisher::~TCPPublisher()
{close(serverSocket);
}void TCPPublisher::cmdVelCallback(const geometry_msgs::Twist::ConstPtr& msg)
{float velX = msg->linear.x;float angularZ = msg->angular.z;// ROS_INFO("velX : %f, angularZ : %f", velX, angularZ);// 定义字符数组,用于存储转换后的结果char buffer[50]; // 适当调整数组大小以适应你的需求snprintf(buffer, sizeof(buffer), "%f,%f", velX, angularZ);// ROS_INFO("buffer %s", buffer);// 接受连接int clientSocket = accept(serverSocket, NULL, NULL);if (clientSocket == -1) {std::cerr << "Accept failed." << std::endl;close(serverSocket);return;}std::cout << "Connection established with a client." << std::endl;// 发送消息给客户端const char* message = buffer;ROS_INFO("message %s", message);if (send(clientSocket, message, strlen(message), 0) == -1) {std::cerr << "Error sending message." << std::endl;}// 关闭客户端套接字close(clientSocket);
}int main(int argc, char **argv) {//创建节点ros::init(argc, argv, "pure_pursuit");TCPPublisher tp;  ros::spin();return 0;
}

客户端代码

#include <rclcpp/rclcpp.hpp>
#include <geometry_msgs/msg/twist.hpp>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>int main(int argc, char * argv[]) {rclcpp::init(argc, argv);auto node = std::make_shared<rclcpp::Node>("tcp_client");/*define publisher*/rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr cmd_pub_;// Advertise velocity commandsauto default_qos = rclcpp::QoS(rclcpp::SystemDefaultsQoS());cmd_pub_ = node->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", default_qos);//连接到服务器// if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {//     std::cerr << "Connection failed." << std::endl;//     close(clientSocket);//     return 1;// }// std::cout << "Connected to the server." << std::endl;while (true) {// 创建客户端套接字int clientSocket = socket(AF_INET, SOCK_STREAM, 0);if (clientSocket == -1) {std::cerr << "Failed to create client socket." << std::endl;return 1;}// 设置服务器地址结构sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // 本地回环地址 // 服务器的 IP 地址serverAddr.sin_port = htons(8080); // 服务器监听的端口号// 连接到服务器if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {std::cerr << "Connection failed." << std::endl;close(clientSocket);// return 1;}// std::cout << "Connected to the server." << std::endl;// 接收消息char buffer[50];memset(buffer, 0, sizeof(buffer));if (recv(clientSocket, buffer, sizeof(buffer), 0) == -1) {std::cerr << "Error receiving message." << std::endl;} else {std::cout << "Received message from server: " << buffer << std::endl;// 定义两个变量来存储解析后的浮点数float floatValue1, floatValue2;// 使用 sscanf 解析字符数组if (std::sscanf(buffer, "%f,%f", &floatValue1, &floatValue2) == 2) {// 打印解析结果std::cout << "解析后的浮点数1: " << floatValue1 << std::endl;std::cout << "解析后的浮点数2: " << floatValue2 << std::endl;} else {// 解析失败std::cerr << "解析失败" << std::endl;}geometry_msgs::msg::Twist cmd_msg;cmd_msg.linear.x = floatValue1;cmd_msg.angular.z = floatValue2;cmd_pub_->publish(cmd_msg);std::cout << "Publishing zero speed to /cmd_vel. " << std::endl;}// 关闭客户端套接字close(clientSocket);// 在这里可以添加一些延时,以避免过于频繁地连接服务器sleep(0.1);}rclcpp::spin(node);rclcpp::shutdown();return 0;
}

到此这篇关于C++实现本地TCP通讯的示例代码的文章就介绍到这了

相关文章:

[C++]C++实现本地TCP通讯的示例代码

这篇文章主要为大家详细介绍了C如何利用TCP技术,实现本地ROS1和ROS2的通讯,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下 概要服务端代码 头文件源代码客户端代码 概要 利用TCP技术&#xff0c;实现本地ROS1和ROS2的通讯。 服务端代码 头文件 #include &…...

Sora - 探索AI视频模型的无限可能

文章目录 每日一句正能量前言技术解析应用场景未来展望伦理与创意用户体验与互动后记 每日一句正能量 . 一个人&#xff0c;如果没有经受过投资失败的痛楚&#xff0c;又怎么会看到绝望之后的海阔天空。很多时候&#xff0c;经历了人生中最艰难的事&#xff0c;反而锻造了最坚强…...

【JavaScript 漫游】【022】事件模型

文章简介 本篇文章为【JavaScript 漫游】专栏的第 022 篇文章&#xff0c;对 JavaScript 中事件模型相关的知识点进行了总结。 监听函数 浏览器的事件模型&#xff0c;就是通过监听函数&#xff08;listener&#xff09;对事件做出反应。事件发生后&#xff0c;浏览器监听到…...

【加密算法】RSA非对称加密算法简介

目录 前言 工作原理 密钥生成 加密和解密 在Java中使用RSA 生成密钥对 加密和解密数据 加密数据 解密数据 注意事项和最佳实践 结论 前言 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是一种基于数论的非对称加密算法&#xff0c;广泛应用于数字签名、数据加密…...

深入理解 JavaScript 对象原型,解密原型链之谜(上)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

产品经理学习-产品运营《什么是SOP》

目录 什么是SOP 如何执行SOP 执行SOP的重点 什么是SOP SOP就是项目流程操作的说明书 日常工作中的例行操作&#xff1a; 例行操作是指&#xff0c;在每一天&#xff0c;针对每一个用户&#xff0c;在每个项目之中&#xff0c;都必须完成的操作&#xff0c;这些必须完成的操…...

大数据Hadoop生态圈

存储&#xff1a; HDFS(namenode,datanode) 计算&#xff1a;MapReduce(mapreduce&#xff0c;基于磁盘) 便于用sql操作&#xff1a;Hive(核心 metastore&#xff0c;存储这些结构化的数据)&#xff0c;同类的还有Impala&#xff0c;hbase等 基于yaml的资源调度 hive &…...

算法简介:查找与算法运行时间

文章目录 1. 二分查找与简单查找1.1 运行时间 2. 旅行商问题 算法是一组完成任务的指令。任何代码片段都可以视为算法。 1. 二分查找与简单查找 二分查找是一种算法&#xff0c;其输入是一个有序的元素列表&#xff0c;如果要查找的元素包含在列表中&#xff0c;二分查找返回…...

零基础C++开发上位机--基于QT5.15的串口助手(三)

本系列教程本着实践的目的&#xff0c;争取每一节课都带大家做一个小项目&#xff0c;让大家多实践多试验&#xff0c;这样才能知道自己学会与否。 接下来我们这节课&#xff0c;主要学习一下QT的串口编程。做一款自己的串口助手&#xff0c;那么这里默认大家都是具备串口通信…...

Facebook的虚拟社交愿景:元宇宙时代的新起点

在当今数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分。而随着科技的不断进步和社会的发展&#xff0c;元宇宙已经成为了人们关注的热点话题之一。作为社交媒体的领军企业之一&#xff0c;Facebook也在积极探索虚拟社交的未来&#xff0c;将其视为元宇宙时…...

【深度学习笔记】4_6 模型的GPU计算

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 4.6 GPU计算 到目前为止&#xff0c;我们一直在使用CPU计算。对复杂的神经网络和大规模的数据来说&#xff0c;使用CPU来计算可能不够…...

留学申请过程中如何合理使用AI?大学招生官怎么看?

我们采访过的学生表示&#xff0c;他们在写essay的过程中会使用 ChatGPT&#xff0c;主要用于以下两个方面&#xff1a;第一&#xff0c;生成想法和头脑风暴&#xff1b;第二&#xff0c;拼写和语法检查。 纽约时报的娜塔莎辛格&#xff08;Natasha Singer&#xff09;在一篇文…...

vue2与vue3的diff算法有什么区别

在 Vue 中&#xff0c;虚拟 DOM 是一种重要的概念&#xff0c;它通过将真实的 DOM 操作转化为对虚拟 DOM 的操作&#xff0c;从而提高应用的性能。Vue 框架在虚拟 DOM 的更新过程中采用了 Diff 算法&#xff0c;用于比较新旧虚拟节点树&#xff0c;找出需要更新的部分&#xff…...

ES小总结

组合查询 FunctionScoreQueryBuilder functionScoreQuery QueryBuilders.functionScoreQuery(boolQuery,new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("isAD",true),Score…...

vue2与vue3中父子组件传参的区别

本次主要针对vue中父子组件传参所进行讲解 一、vue2和vue3父传子区别 1.vue2的父传子 1).在父组件子标签中自定义一个属性 <sonPage :子组件接收到的类名"传输的数据">子组件</sonPage> 2).在子组件中peops属性中拿到自定属性 props: {子组件接收的…...

使用vuetify实现全局v-alert消息通知

前排提示&#xff0c;本文为引流文&#xff0c;文章内容不全&#xff0c;更多信息前往&#xff1a;oldmoon.top 查看 简介 使用强大的Vuetify开发前端页面&#xff0c;结果发现官方没有提供简便的全局消息通知组件&#xff08;像Element中的ElMessage那样&#xff09;&#xf…...

CentOS 7.9上编译wireshark 3.6

工作环境是Centos 7.9&#xff0c;原本是通过flathub安装的wireshark&#xff0c;但是在gnome的application installer上升级到wireshark 4.2.3之后就运行不起来了&#xff0c;flatpak run org.wireshark.Wireshark启动提示缺少qt6&#xff0c;查了一下wireshark新版是依赖qt6的…...

初学学习408之数据结构--数据结构基本概念

初学学习408之数据结构我们先来了解一下数据结构的基本概念。 数据结构&#xff1a;是相互之间存在一种或多种特定关系的数据元素的集合。 本内容来源于参考书籍《大话数据结构》与《王道数据结构》。除去书籍中的内容&#xff0c;作为初学者的我会尽力详细直白地介绍数据结构的…...

Java项目中必须使用本地缓存的几种情况

Java项目中必须使用本地缓存的几种情况 在Java项目的开发过程中&#xff0c;为了提高应用的性能和响应速度&#xff0c;缓存机制经常被使用。其中&#xff0c;本地缓存作为一种常见的缓存方式&#xff0c;将数据存储在应用程序的本地内存或磁盘中&#xff0c;以便快速访问。下…...

【鸿蒙 HarmonyOS 4.0】TypeScript开发语言

一、背景 HarmonyOS 应用的主要开发语言是 ArkTS&#xff0c;它由 TypeScript&#xff08;简称TS&#xff09;扩展而来&#xff0c;在继承TypeScript语法的基础上进行了一系列优化&#xff0c;使开发者能够以更简洁、更自然的方式开发应用。值得注意的是&#xff0c;TypeScrip…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...