跨平台Socket传输Protocol Buffer时dWindDirection字段数据损坏求助
dWindDirection Field in Protobuf-over-Socket Setup Hey there! Let’s break down why your dWindDirection field is consistently getting corrupted when sending from your Windows C++ client to the Ubuntu C server. I’ve run into similar cross-platform Protobuf and socket communication issues before, so here are the most likely culprits and fixes:
1. Mismatched Protobuf Definitions
First things first—double-check that your .proto files are exactly identical on both client and server. Even a tiny difference (like using float instead of double for dWindDirection, or a mismatched field number) will throw off parsing, especially for the last field where alignment errors tend to surface.
Example of a correct, consistent definition:
message FlightData { // ... other fields ... double dWindDirection = 10; // Ensure field number and type match on both ends }
2. Incorrect Message Length Handling
This is the most common issue with socket-Protobuf setups. If you’re not sending/receiving the exact byte length of the serialized Protobuf message, the last field will get truncated or overwritten with garbage data.
Client Side (Windows C++) Fix
Make sure you send the actual serialized length, not the full size of your buffer:
FlightData flight_msg; // Populate fields with SimConnect data... // Serialize to a buffer char send_buf[1024]; int serialized_len = flight_msg.SerializeToArray(send_buf, sizeof(send_buf)); // Send ONLY the serialized bytes, not the entire buffer send(client_socket, send_buf, serialized_len, 0);
Server Side (Ubuntu C) Fix
Don’t assume you’ll receive the full message in one recv() call, and don’t parse using the buffer size. Instead:
- First send a 4-byte header with the message length (convert to network byte order with
htonl()on client,ntohl()on server). - Receive the length, then allocate a buffer for exactly that many bytes.
- Receive the full message before parsing.
Example server code:
// Step 1: Receive message length (convert from network byte order) uint32_t msg_len; recv(server_socket, &msg_len, sizeof(msg_len), 0); msg_len = ntohl(msg_len); // Step 2: Allocate buffer and receive full message char* recv_buf = malloc(msg_len); recv(server_socket, recv_buf, msg_len, 0); // Step 3: Parse with the exact serialized length FlightData flight_msg; if (flight_msg.ParseFromArray(recv_buf, msg_len)) { printf("Wind Direction: %lf\n", flight_msg.dWindDirection()); } else { fprintf(stderr, "Failed to parse Protobuf message\n"); } free(recv_buf);
3. Unhandled Endianness (Less Likely, But Worth Checking)
While Protobuf uses little-endian encoding by default (which matches x86/x64 systems like Windows and Ubuntu), if you’re manually converting SimConnect data to Protobuf fields (instead of letting Protobuf handle serialization), double-check you’re not flipping bytes unnecessarily.
For example, if SimConnect returns a big-endian value, you’ll need to convert it to host byte order before setting it in the Protobuf message.
4. Debug with Wire Format Comparison
If the above fixes don’t work, print the raw hex bytes of the serialized message on the client right before sending, and on the server right after receiving. If the hex strings don’t match exactly, you have a socket transmission issue (like partial sends/receives). If they do match, the problem is definitely in your Protobuf definition or parsing code.
Client debug code:
std::string serialized_str; flight_msg.SerializeToString(&serialized_str); printf("Serialized bytes (hex): "); for (unsigned char c : serialized_str) { printf("%02X ", c); } printf("\n");
Server debug code:
// After receiving recv_buf and msg_len printf("Received bytes (hex): "); for (int i = 0; i < msg_len; i++) { printf("%02X ", (unsigned char)recv_buf[i]); } printf("\n");
Final Notes
The fixed corrupted value you’re seeing is a dead giveaway that parsing is offset—either because the message length was wrong, or the Protobuf schema doesn’t align. Start with checking the schema and length handling, those are almost always the root cause here.
内容的提问来源于stack exchange,提问作者Nbreen

