欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)本地TCP通訊的示例代碼

 更新時間:2024年02月23日 08:32:39   作者:點PY  
這篇文章主要為大家詳細介紹了C++如何利用TCP技術(shù),實現(xiàn)本地ROS1和ROS2的通訊,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

概要

利用TCP技術(shù),實現(xiàn)本地ROS1和ROS2的通訊。

服務(wù)端代碼

頭文件

#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;
        // 創(chuàng)建服務(wù)器套接字
        int serverSocket;
        // 設(shè)置服務(wù)器地址結(jié)構(gòu)
        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);
    // 設(shè)置服務(wù)器地址結(jié)構(gòu)
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(8080); // 服務(wù)器監(jiān)聽的端口號

    // 綁定套接字
    if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        std::cerr << "Bind failed." << std::endl;
        close(serverSocket);
        return;
    }

    // 監(jiān)聽連接
    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);

    // 定義字符數(shù)組,用于存儲轉(zhuǎn)換后的結(jié)果
    char buffer[50]; // 適當(dāng)調(diào)整數(shù)組大小以適應(yīng)你的需求
    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;

    // 發(fā)送消息給客戶端
    const char* message = buffer;
    ROS_INFO("message %s", message);

    if (send(clientSocket, message, strlen(message), 0) == -1) {
        std::cerr << "Error sending message." << std::endl;
    }

    // 關(guān)閉客戶端套接字
    close(clientSocket);
}

int main(int argc, char **argv) {
  //創(chuàng)建節(jié)點
  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 commands
    auto default_qos = rclcpp::QoS(rclcpp::SystemDefaultsQoS());
    cmd_pub_ = node->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", default_qos);


    //連接到服務(wù)器
    // 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) {

        // 創(chuàng)建客戶端套接字
        int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (clientSocket == -1) {
            std::cerr << "Failed to create client socket." << std::endl;
            return 1;
        }

        // 設(shè)置服務(wù)器地址結(jié)構(gòu)
        sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // 本地回環(huán)地址 // 服務(wù)器的 IP 地址
        serverAddr.sin_port = htons(8080); // 服務(wù)器監(jiān)聽的端口號

        // 連接到服務(wù)器
        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;

            // 定義兩個變量來存儲解析后的浮點數(shù)
            float floatValue1, floatValue2;

            // 使用 sscanf 解析字符數(shù)組
            if (std::sscanf(buffer, "%f,%f", &floatValue1, &floatValue2) == 2) {
                // 打印解析結(jié)果
                std::cout << "解析后的浮點數(shù)1: " << floatValue1 << std::endl;
                std::cout << "解析后的浮點數(shù)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;
        }

        // 關(guān)閉客戶端套接字
        close(clientSocket);
        // 在這里可以添加一些延時,以避免過于頻繁地連接服務(wù)器
        sleep(0.1);
    }



    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

到此這篇關(guān)于C++實現(xiàn)本地TCP通訊的示例代碼的文章就介紹到這了,更多相關(guān)C++ TCP通訊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++常見異常處理原理及代碼示例解析

    C++常見異常處理原理及代碼示例解析

    這篇文章主要介紹了C++常見異常處理原理及代碼示例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • C++ vector容器實現(xiàn)貪吃蛇小游戲

    C++ vector容器實現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細介紹了C++ vector容器實現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C語言正則表達式詳解 regcomp() regexec() regfree()用法詳解

    C語言正則表達式詳解 regcomp() regexec() regfree()用法詳解

    C語言處理正則表達式常用的函數(shù)有regcomp()、regexec()、regfree()和regerror(),這里就為大家介紹一下,需要的朋友可以參考一下啊
    2018-04-04
  • Ubuntu18.04下QT開發(fā)Android無法連接設(shè)備問題解決實現(xiàn)

    Ubuntu18.04下QT開發(fā)Android無法連接設(shè)備問題解決實現(xiàn)

    本文主要介紹了Ubuntu18.04下QT開發(fā)Android無法連接設(shè)備問題解決實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言實現(xiàn)wave波形

    C語言實現(xiàn)wave波形

    本文詳細講解了C語言實現(xiàn)wave波形的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-12-12
  • C語言算法的定義及分析詳解

    C語言算法的定義及分析詳解

    這篇文章主要為大家詳細介紹了C語言算法的定義及分析,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 教你分辨C++堆與棧的區(qū)別

    教你分辨C++堆與棧的區(qū)別

    堆與棧的區(qū)別有:1、棧由系統(tǒng)自動分配,而堆是人為申請開辟;2、棧獲得的空間較小,而堆獲得的空間較大;3、棧由系統(tǒng)自動分配,速度較快,而堆一般速度比較慢;4、棧是連續(xù)的空間,而堆是不連續(xù)的空間
    2021-06-06
  • 詳解C++17中類模板參數(shù)推導(dǎo)的使用

    詳解C++17中類模板參數(shù)推導(dǎo)的使用

    自C++17起就通過使用類模板參數(shù)推導(dǎo),只要編譯器能根據(jù)初始值推導(dǎo)出所有模板參數(shù),那么就可以不指明參數(shù),下面我們就來看看C++17中類模板參數(shù)推導(dǎo)的具體使用吧
    2024-03-03
  • C++中的字符串編碼處理方法

    C++中的字符串編碼處理方法

    這篇文章主要介紹了C++中的字符串編碼處理,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • 舉例講解C語言的fork()函數(shù)創(chuàng)建子進程的用法

    舉例講解C語言的fork()函數(shù)創(chuàng)建子進程的用法

    fork函數(shù)是Linux下一個近乎專有的C語言函數(shù),因為使用時需要調(diào)用unistd.h這個頭文件,這里我們就在Linux環(huán)境下舉例講解C語言的fork()函數(shù)創(chuàng)建子進程的用法,需要的朋友可以參考下
    2016-06-06

最新評論