socket 传输结构体数据,另一端进行恢复
common.h
#pragma once#include <cstring>
#include <iostream>// 要传输的结构体
#pragma pack(push, 1) // 不要添加任何填充,按 1 字节对齐
struct Person {int id;char name[32];float height;bool married;// 构造函数(可选)Person() : id(0), height(0.0f), married(false) {std::memset(name, 0, sizeof(name));}// 打包函数:将结构体序列化为字节数组void pack(char* buffer) const {std::cout << sizeof(Person) << std::endl;std::memcpy(buffer, this, sizeof(Person));}// 解包函数:从字节数组还原结构体void unpack(const char* buffer) {std::memcpy(this, buffer, sizeof(Person));}// 打印信息void print() const {std::cout << "ID: " << id<< ", Name: " << name<< ", Height: " << height<< ", Married: " << (married ? "Yes" : "No")<< std::endl;}
};#pragma pack(pop)// 固定大小,用于传输
static_assert(sizeof(Person) == 41, "Person struct size must be 41 bytes");
// serverreceiver.cpp
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include "common.h"int main() {const int PORT = 8888;int server_sock, client_sock;struct sockaddr_in server_addr, client_addr;socklen_t client_len = sizeof(client_addr);server_sock = socket(AF_INET, SOCK_STREAM, 0);if (server_sock < 0) {std::cerr << "Socket creation failed\n";return -1;}int opt = 1;setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {std::cerr << "Bind failed\n";close(server_sock);return -1;}if (listen(server_sock, 1) < 0) {std::cerr << "Listen failed\n";close(server_sock);return -1;}std::cout << "Waiting for connection...\n";client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len);if (client_sock < 0) {std::cerr << "Accept failed\n";close(server_sock);return -1;}std::cout << "Client connected.\n";// 接收结构体char buffer[sizeof(Person)];ssize_t received = recv(client_sock, buffer, sizeof(Person), 0);if (received == sizeof(Person)) {Person person;person.unpack(buffer);std::cout << "Received: ";person.print();} else {std::cerr << "Receive failed or incomplete data\n";}close(client_sock);close(server_sock);return 0;
}
clientsender.cpp
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include "common.h"int main() {const char* SERVER_IP = "127.0.0.1";const int PORT = 8888;int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0) {std::cerr << "Socket creation failed\n";return -1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(PORT);inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {std::cerr << "Connect failed\n";close(sock);return -1;}std::cout << "Connected to receiver.\n";// 创建结构体实例Person person;person.id = 1001;std::strcpy(person.name, "Alice");person.height = 1.68f;person.married = true;person.print(); // 打印发送的内容// 发送结构体char buffer[sizeof(Person)];person.pack(buffer);ssize_t sent = send(sock, buffer, sizeof(Person), 0);if (sent == sizeof(Person)) {std::cout << "Person struct sent successfully.\n";} else {std::cerr << "Send failed\n";}close(sock);return 0;
}