最近遇到了跨语言的进行数据交互的问题,就是通过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类型的嵌套结构体的示例,如果需要传输其他类型的文件只要改一下代码即可。