#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>
#include <winsock2.h>
struct MyStruct {
int intValue;
float floatValue;
// Add more members as needed
struct MyInnerStruct {
int intValue;
float floatValue;
};
MyInnerStruct *InnerStruct;
};
int main() {
MyStruct testStruct;
testStruct.floatValue = 3.1;
testStruct.intValue = 4;
testStruct.InnerStruct = new MyStruct::MyInnerStruct[4];
for (int i = 0; i < 4; i++) {
testStruct.InnerStruct[i].intValue = i + 23;
testStruct.InnerStruct[i].floatValue = (i/10) + 23;
}
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "Failed to initialize winsock." << std::endl;
return 1;
}
char hostname[256];
char ip[100];
// Get the hostname
if (gethostname(hostname, sizeof(hostname)) == 0) {
std::cout << "Hostname: " << hostname << std::endl;
// Get the IP address
struct hostent* host_info = gethostbyname(hostname);
if (host_info != nullptr) {
struct in_addr* address = reinterpret_cast<struct in_addr*>(host_info->h_addr);
strcpy(ip, inet_ntoa(*address));
std::cout << "IP Address: " << ip << std::endl;
}
else {
std::cerr << "Error getting host information." << std::endl;
}
}
else {
std::cerr << "Error getting hostname." << std::endl;
}
int udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (udpSocket == -1) {
perror("Error creating socket");
exit(EXIT_FAILURE);
}
// Server address
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345); // Choose a port
serverAddr.sin_addr.s_addr = inet_addr(ip); // Replace with the server's IP
// Serialize the struct into a byte stream
char buffer[sizeof(MyStruct)];
memcpy(buffer, &testStruct, sizeof(MyStruct));
// Send the serialized struct over the UDP socket
if (sendto(udpSocket, buffer, sizeof(MyStruct), 0, reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr)) == -1) {
perror("Error sending data");
closesocket(udpSocket);
exit(EXIT_FAILURE);
}
std::cout << "Struct sent successfully." << std::endl;
// Clean up
closesocket(udpSocket);
WSACleanup();
return 0;
}
但是在 python 中我似乎无法获取嵌套的 c++ 结构的值
import socket
import struct
from ctypes import *
# IP address and port number for server
HOST = '127.0.0.1'
PORT = 12345
class MyInnerStruct(Structure):
_fields_ = [
('field4', c_int),
('field5', c_float),
]
class MyStruct(Structure):
_fields_ = [
('field1', c_int),
('field2', c_float),
('field3', POINTER(MyInnerStruct)),
]
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((HOST, PORT))
while True:
data, addr = sock.recvfrom(sizeof(MyStruct))
received_struct = cast(data, POINTER(MyStruct)).contents
# Access the fields of the received struct
field1 = received_struct.field1
field2 = received_struct.field2
field3 = received_struct.field3
received_inner_struct = cast(field3, POINTER(MyInnerStruct)).contents
for i in range(field1):
array[i].field4 = field3[i].field4
array[i].field5 = field3[i].field5 //these lines are not working
# Close the socket
sock.close()
我尝试通过尝试取消引用来访问内部嵌套结构(在for循环中)的值,但我不能,我如何访问内部结构中的字段4和字段5
在 C 中,为每个数组元素发送等效的 field1-3,然后发送 field4-5。这是我用于测试的 Python 等效项:
import struct
import socket
# send field1=4, field2, and 4x the two fields of each array element.
data = struct.pack('<ififififif', 4, 3.5, 1, 1.25, 2, 2.5, 3, 2.75, 4, 3.00)
with socket.socket(type=socket.SOCK_DGRAM) as s:
s.sendto(data, ('localhost', 5000))
一种解压方式,但效率不过分。要接收,请读取前两个字段并初始化
MyStruct
的字段 1-2。使用 field1
分配 MyInnerStruct
数组。然后从缓冲区中读取 field4-5 对并初始化数组。最后,将数组分配给MyStruct.field3
:
import socket
import struct
import ctypes as ct
class MyInnerStruct(ct.Structure):
_fields_ = (('field4', ct.c_int),
('field5', ct.c_float))
def __repr__(self): # for display
return f'({self.field4}, {self.field5})'
class MyStruct(ct.Structure):
_fields_ = (('field1', ct.c_int),
('field2', ct.c_float),
('field3', ct.POINTER(MyInnerStruct)))
def __repr__(self): # for display
return f'[{self.field1}, {self.field2}, {list(self.field3[:self.field1])})]'
sock = socket.socket(type=socket.SOCK_DGRAM)
sock.bind(('', 5000))
data, addr = sock.recvfrom(40960)
field1, field2 = struct.unpack_from('<if', data)
received_struct = MyStruct(field1, field2) # pointer is null at this point
inner_array = (MyInnerStruct * field1)() # allocate inner array
start_of_inner = struct.calcsize('if') # index data after MyStruct fields
size_of_inner = struct.calcsize('if') # size of inner array element
index = start_of_inner
for i in range(field1):
field4, field5 = struct.unpack_from('<if', data[index:]) # read fields of an array element
inner_array[i] = MyInnerStruct(field4, field5) # assign to the array element
index += size_of_inner
received_struct.field3 = inner_array # pointer to the initialized inner array
print(received_struct) # now print complete received item.
运行接收者代码等待数据包,然后运行发送者代码发送数据包:
接收器输出:
[4, 3.5, [(1, 1.25), (2, 2.5), (3, 2.75), (4, 3.0)])]