You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python TCP Socket接收C++结构体数据并解析展示的示例请求

问题分析

原C++代码的核心问题是直接memcpy包含std::string的结构体完全不可行:std::string内部存储的是指向堆内存的指针,sizeof(student)仅计算了指针、int数组、float的固定大小,并没有包含字符串的实际内容。发送后Python端拿到的只是无效的指针地址,根本无法还原真实字符串。

正确的C++序列化与发送实现

需要手动将结构体序列化为可传输的字节流,按固定格式依次发送每个字段的内容,示例代码如下:

#include <vector>
#include <cstring>
#include <arpa/inet.h> // 用于字节序转换

typedef struct {
    int enable;
    std::string name;
    int numbers[5];
    float counter;
} Student;

// 序列化Student结构体为字节流
std::vector<uint8_t> serializeStudent(const Student& student) {
    std::vector<uint8_t> data;

    // 序列化enable:转换为网络字节序(大端)
    uint32_t enable_be = htonl(student.enable);
    data.insert(data.end(), reinterpret_cast<uint8_t*>(&enable_be), 
                reinterpret_cast<uint8_t*>(&enable_be) + sizeof(enable_be));

    // 序列化name:先发送字符串长度(网络字节序),再发送字符串内容
    uint32_t name_len_be = htonl(student.name.size());
    data.insert(data.end(), reinterpret_cast<uint8_t*>(&name_len_be), 
                reinterpret_cast<uint8_t*>(&name_len_be) + sizeof(name_len_be));
    data.insert(data.end(), student.name.begin(), student.name.end());

    // 序列化numbers数组:每个int转换为网络字节序
    for (int num : student.numbers) {
        uint32_t num_be = htonl(num);
        data.insert(data.end(), reinterpret_cast<uint8_t*>(&num_be), 
                    reinterpret_cast<uint8_t*>(&num_be) + sizeof(num_be));
    }

    // 序列化counter:先转为uint32_t再处理字节序
    uint32_t counter_raw;
    std::memcpy(&counter_raw, &student.counter, sizeof(counter_raw));
    uint32_t counter_be = htonl(counter_raw);
    data.insert(data.end(), reinterpret_cast<uint8_t*>(&counter_be), 
                reinterpret_cast<uint8_t*>(&counter_be) + sizeof(counter_be));

    return data;
}

// TCP发送函数示例
void sendDataOverTCPSocket(const std::vector<uint8_t>& data, int sockfd) {
    send(sockfd, data.data(), data.size(), 0);
}

// 使用示例
// Student s{1, "Alice", {10,20,30,40,50}, 3.14f};
// auto serialized_data = serializeStudent(s);
// sendDataOverTCPSocket(serialized_data, your_socket_fd);
Python服务器端解析实现

基于基础TCP服务器框架,按C++的序列化格式反向解析数据:

import socket
import struct

def parse_student(raw_data):
    offset = 0

    # 解析enable:网络字节序转主机字节序
    enable = struct.unpack('!I', raw_data[offset:offset+4])[0]
    offset += 4

    # 解析name的长度与内容
    name_len = struct.unpack('!I', raw_data[offset:offset+4])[0]
    offset +=4
    name = raw_data[offset:offset+name_len].decode('utf-8')
    offset += name_len

    # 解析numbers数组
    numbers = []
    for _ in range(5):
        num = struct.unpack('!I', raw_data[offset:offset+4])[0]
        numbers.append(num)
        offset +=4

    # 解析counter:先还原uint32_t再转float
    counter_raw = struct.unpack('!I', raw_data[offset:offset+4])[0]
    counter = struct.unpack('f', struct.pack('I', counter_raw))[0]
    offset +=4

    return {
        'enable': enable,
        'name': name,
        'numbers': numbers,
        'counter': counter
    }

def main():
    host = '0.0.0.0'
    port = 12345

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(5)

    print(f"Server listening on {host}:{port}")

    while True:
        client_socket, addr = server_socket.accept()
        print(f"Connected to {addr}")

        # 接收数据:生产环境需处理粘包,可先接收总长度再接收对应字节数
        raw_data = client_socket.recv(1024)
        if not raw_data:
            client_socket.close()
            continue

        student_info = parse_student(raw_data)
        print("\nReceived Student Data:")
        print(f"Enable: {student_info['enable']}")
        print(f"Name: {student_info['name']}")
        print(f"Numbers: {student_info['numbers']}")
        print(f"Counter: {student_info['counter']:.2f}")

        client_socket.close()

if __name__ == "__main__":
    main()
关键注意事项
  • 字节序一致性:C++用htonl转换为网络字节序(大端),Python用!格式符对应网络字节序,避免跨平台解析错误
  • 粘包处理:实际生产环境中,需先发送序列化数据的总长度,Python端先接收长度再读取对应字节数的内容,防止粘包
  • 字符串编码:示例使用UTF-8编码,C++和Python需保持编码一致
  • float解析:通过先转换为uint32_t处理字节序,再转回float,保证浮点值解析正确

内容的提问来源于stack exchange,提问作者jkafernando

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:15:40