Socket通信---Python发送数据给C++程序

0. Problems

很多时候实现某种功能,需要在不同进程间发送数据,目前有几种主流的方法,如
让python和C/C++程序互相发送数据,其实有几种方法:

  • 共享内存
  • 共享文件
  • Socket通信

在这里只提供Socket通信的例程,共享文件很容易实现,就是可靠性差点,共享内存也是一种常用的方法。

其实,如果使用的是ROS框架,更加方便,提供了三种通信方法 (Topic/Server/Action),具体内容可以看我之前的ROS Learning篇的内容,请点这里

1. Solutions

先上例程

1)Python端发送:
import socket
import json

# 创建Socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接C++程序
cpp_host = '127.0.0.1'  # C++程序所在的主机
cpp_port = 8888  # C++程序监听的端口
sock.connect((cpp_host, cpp_port))

# 读取json文件并发送给C++程序
with open('response.json', 'r') as file:
    json_data = file.read()
    sock.sendall(json_data.encode())

# 接收C++程序的响应
response = sock.recv(1024).decode()
if len(response) > 0:
    print("Received response from C++ program:", response)
else:
    print("Failed to receive response from C++ program.")

# 关闭Socket连接
sock.close()
2)C++端接收:
/*
 * @Descripttion: Robot2.5
 * @version: 20220211
 * @Author: Will Yip
 * @Date: 2024-02-21 15:43:37
 * @LastEditors: Will Yip
 * @LastEditTime: 2024-02-21 16:25:42
 */
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    // 创建Socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    // 绑定Socket到指定端口
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8888);  // 监听的端口
    addr.sin_addr.s_addr = INADDR_ANY;

    bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));

    // 监听连接
    listen(sockfd, 1);

    // 接受连接
    sockaddr_in clientAddr{};
    socklen_t clientAddrLen = sizeof(clientAddr);
    int clientSock = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen);

    // 接收来自Python程序的数据
    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    int bytesRead = recv(clientSock, buffer, sizeof(buffer), 0);

    // 判断是否接收到了数据
    if (bytesRead > 0) {
        // 处理收到的数据(这里假设数据是JSON格式)
        std::cout << "Received JSON data from Python program: " << buffer << std::endl;

        // 发送响应给Python程序
        const char* response = "Data received successfully!";
        send(clientSock, response, strlen(response), 0);
    } else {
        std::cout << "Failed to receive data from Python program." << std::endl;
    }

    // 关闭连接
    // close(clientSock); // dont close this connection, it will causes a problem when relaunch this receiver next time, it cant create 8888 port.
    close(sockfd);

    return 0;
}

然后就可以开始测试了,记住要先启动C++接收端,再启动python发送端,不然就报错,提示connection error


在调试时也会用上一些指令,可以帮助我们做一些检查

在Ubuntu中有两个常用的指令用来查看端口情况:

  • netstat
  • lsof

这两个指令都能显示当前的端口信息。

  1. netstat
    常用netstat -tuln,加上后面的参数可以帮助显示TCP和UDP协议的端口
    • -t表示显示TCP协议的端口;
    • -u表示显示UDP协议的端口;
    • -l表示仅显示监听状态的端口;
    • -n表示以数字形式显示地址和端口号,而不是尝试解析主机名、服务名等。

显示如下: netstat

  1. lsof
    lsof的用法是lsof -i:port_num,里面的port_num就是端口号,可以是根据netstat查询到的端口号。
    PS:端口号前加不加空格都行,
    以下是示例:
    lsof
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值