0

As an example have the below struct, and I am sending this over a tcp socket. When I receive the data on the tcp socket, how do I reconstruct the struct information? ( how do I convert the tcp data to be printed on the console)

//data struct
typedef struct {
    int enable;
    string name;
    int numbers[5];
    float counter;
}Student;

//convert data to uint8 and send over tcp socket
uint32_t size = sizeof(student);
std:vector<std::uint8_t> data(size);
std::memcpy(data.data(), reinterpret_cast<void*>(&student),size)
sendDataOverTCPSocket(data);

Appreciate an example on how to do this. Thank you

7
  • 1
    Creating a byte-array on the recieving side in the right size, memcopy-ing the data in there, then casting the pointer back to a student* might work. It's really not a good idea though: If a single bit gets misalined during transfer, your object is now corrupt, and you'll never know. How about adding a .tostring() and .fromstring() (or JSON or XML, ...) function to your struct to serialize/deserialize it ? Commented Nov 16, 2022 at 11:34
  • 1
    Your struct contains a std::string name, and cannot be trivially copied with memcpy (and sizeof will not work as you expect either). You need to serialize it. Commented Nov 16, 2022 at 11:39
  • the struct does not contain the name but only a pointer to the name Commented Nov 16, 2022 at 11:44
  • how do I create serialize and deserialize in C++ Commented Nov 16, 2022 at 11:45
  • You write a function that converts data from struct into uint8 array Commented Nov 16, 2022 at 11:47

1 Answer 1

5

You should not send the raw bytes like this through a network socket. C++ provides very little guarantees about the actual memory layout of structs. If you happen to have the programs on both endpoints compiled with different compiler versions (or for different platforms) you might end up with different memory layouts. Even worse is the handling of std::string objects. Those might allocate memory dynamically on the heap and only store a pointer to that memory. Your code as is would only send the pointer and not the memory. On the receiving site you will get a segmentation fault almost for sure.

For example int might be 4 bytes on one machine and 8 bytes on another one. If you try to reconstruct the struct sent by the first machine on the second one, you will end up with corrupted invalid data.


You should do either from the following instead:

  • Write a serialization and deserialization function for your class on your own. You need to specify how long exactly each member is (use int64_t or int32_t instead of int for example) and take into account the potential for different byte ordering. On unix-like systems you could use for example these endianess conversion functions. You also must serialize the string in some way that the length can be reconstructed.
  • Use a serialization library like for example boost serialization.
  • Use a popular data exchange format like for example json. There are libraries (like JSON for Modern C++, rapidjson or boost json that allow you to easily convert your struct to json or the other way around.

For example, you can find a live example of how to do a json serialization with boost json here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.