python与c的socket通信,处理c嵌套结构体

    最近遇到了跨语言的进行数据交互的问题,就是通过python客户端向c的服务端传输c的嵌套结构体。

C的服务端:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define PORT 5233
# include <stdio.h>
# include <stdlib.h>

typedef struct
{
    int    seq;
    int    len;
}msg_hdr_t;


#define size   1024
typedef struct
{
    unsigned int    msgid;
    unsigned int    wparam;
    unsigned int    lparam;
    unsigned int    seqnum;
    unsigned int    framerate;
    unsigned int    data_size;
    unsigned char   data[size];
}msg_body_t;


typedef struct
{
    msg_hdr_t  hdr;
    msg_body_t body;
}msg_t;

void parse(auto_msg_t  msg_t) {
    cout << "hdr.len: " << msg_t.hdr.len << endl;
    cout << "hdr.seq: " << msg_t.hdr.seq << endl;
    cout << "body.msgid: " << msg_t.body.msgid << endl;
    cout << "body.wparam: " << msg_t.body.wparam << endl;
    cout << "body.lparam: " << msg_t.body.lparam << endl;
    cout << "body.seqnum: " << msg_t.body.seqnum << endl;
    cout << "body.framerate: " << msg_t.body.framerate << endl;
    cout << "body.data: " << msg_t.body.data << endl;
}

int main()
{
    WSADATA wsaData;
    WSAStartup(0x0202, &wsaData); //初始化Socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);//UDP
    if (INVALID_SOCKET == sock)
    {
        cout << "创建socket套接字出错:" << WSAGetLastError() << endl;
        return -1;
    }
    sockaddr_in sa = { 2 };
    sa.sin_port = htons(PORT);//绑定的端口
    sa.sin_addr.S_un.S_addr = 0;//绑定本机所有IP

    int n = bind(sock, (sockaddr*)&sa, sizeof(sa));
    if (SOCKET_ERROR == n)
    {
        cout << "绑定时套接字时出错:" << WSAGetLastError() << endl;
        return -1;
    }
    //监听
    listen(sock, 5);

    SOCKET socka = INVALID_SOCKET;

    char str[2048];
    msg_t test;
    cout << "start test" << endl;
    while (true)
    {
        socka = accept(sock, NULL, NULL);
        const char* p = "Welcome to connect";
        send(socka, p, strlen(p), 0);
        while (true)
        {
            int n = recv(socka, str, sizeof(str), 0);
            if (n <= 0)
                break;
            str[n] = 0;
            memcpy(&test, str, sizeof(msg_t) + 1);
            parse(test);

        }
    }
    closesocket(socka);
    closesocket(sock);
    WSACleanup();
    return 0;
}

python客户端

import ctypes
from ctypes import *
import socket

SIZE = 1024


class msg_hdr_t(ctypes.Structure):
    _fields_ = [
        ("seq", ctypes.c_int),
        ("len", ctypes.c_int)
    ]


class msg_body_t(ctypes.Structure):
    _fields_ = [
        ("msgid", ctypes.c_uint),
        ("wparam", ctypes.c_uint),
        ("lparam", ctypes.c_uint),
        ("seqnum", ctypes.c_uint),
        ("framerate", ctypes.c_uint),
        ("data_size", ctypes.c_uint),
        #无符号字符数组
        ("data", ctypes.c_char * SIZE),
    ]


class msg_t(ctypes.Structure):
    _fields_ = [
        ("msg_hdr_t", msg_hdr_t),
        ("msg_body_t", msg_body_t)
    ]


msg_t = msg_t()

def parse_msg_struct(msg_struct, seq, msgid, wparam, lparam, seqnum, framerate, datasize, data):
    msg_struct.msg_hdr_t.seq = seq
    # 这里需要获取嵌套结构体的size
    msg_struct.msg_hdr_t.len = ctypes.sizeof(msg_struct)
    msg_struct.msg_body_t.msgid = msgid
    msg_struct.msg_body_t.wparam = wparam
    msg_struct.msg_body_t.lparam = lparam
    msg_struct.msg_body_t.seqnum = seqnum
    msg_struct.msg_body_t.framerate = framerate
    msg_struct.msg_body_t.data_size = datasize
    msg_struct.msg_body_t.data = data
    return msg_struct


def socket_client_send_data(ip,port,msg_t):
    while True:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            client.connect((ip, port))
        except socket.error as msg:
            print("%s" % msg)
        
        #阻塞消息,等待输入后发送消息
        i = input(str("input data:"))

        data = parse_msg_struct(msg_t, 1, 12, 22, 1, 4, 30, 1024, b'test-sdk')
        client.send(data)
        print("--------send----------")
        data = client.recv(1024) 
        print("recv:>", data.decode())
        client.close()


if __name__ == '__main__':
    socket_client_send_data('127.0.0.1',5233,msg_t)

程序运行的结果:

c的服务端先启动:

启动python客户端并发送消息:

服务端的解析结果:

     以上就是跨语言传输c类型的嵌套结构体的示例,如果需要传输其他类型的文件只要改一下代码即可。

猜你喜欢

转载自blog.csdn.net/athrunsunny/article/details/121523514
今日推荐