Reputation: 461
I'm working on a C++ socket assignment and I'm trying to send a string from the server to the clients.
const char* msg;
msg = "test";
results in my client printing test
to the console, however when I try the following:
std::string msg;
std::getline(std::cin, msg);
the result printed is gibberish. Before sending I serialize a struct which holds the message and the message is intact. When I check the deserialized package the message is messed up.
I'm using the following struct:
struct Package{
unsigned int package_type;
const char* msg;
int senderid;
int receiveid;
void SerializeData(char* _data){
memcpy(_data, this, sizeof(Package));
}
void DeserializeData(char* _data){
memcpy(this, _data, sizeof(Package));
}
};
Any idea why a const char* defined in code works, but a string.c_str() doesn't?
Upvotes: 0
Views: 300
Reputation: 17956
Your SerializeData
and DeserializeData
functions do not actually serialize/deserialize the string at all. They serialize/deserialize a pointer to char
, which is quite different. It's just a pointer!
Passing actual pointers between different processes over a network is seldom meaningful, since each process has its own private address space.
Your example possibly works for "test"
because "test"
is a compile time constant, allocated in the executable itself. If the same executable acts as sender and receiver, it's entirely plausible the constant string will be in the same place on both. (But, not guaranteed. OS hardening features such as Address Space Layout Randomization will break that.) Pointers provided by string.c_str()
are very ephemeral in contrast, and dynamically generated at run time.
You need to actually serialize the string into the packet. That likely entails adding a length field somewhere, or some other means for handling a variable-sized message.
If your assignment is to just send strings from one end to the other, then you can possibly simplify this problem quite a lot. If you need full serialization of arbitrary messages, that gets more complex. You either need some sort of grammar around the message, or some sort of shared expectation of message formats between sender and receiver.
In any case, when you serialize a structure with a pointer or reference, you need to make sure you pull in the pointed-to or referred-to object, not the pointer or reference directly. Fully general serialization isn't easy. As @Sorin indicated elsewhere on the page, Google Protocol Buffers are one way to do this.
Upvotes: 2
Reputation: 11968
Your serialized package contains something like 0 0xabc 0 0
where 0xabc is the pointer in memory where the string is stored. It will not match on the other side.
Dump the serialized package in a hex editor or similar and see if it makes any sense. You probably need to serialize one by one each element and copy the actual string into the serialized package.
This is hard to do. Use some library to do serialization for you. Here's one https://code.google.com/p/protobuf/ but there are others.
Upvotes: 1