Send any type of data over UDP
c++, udp
Solution
You can't just "send" your class. You have to send a representation of the data in your class. And sending a pointer to your class won't work either. When another application on the network receives your pointer, it will be meaningless to them.
Consider this:
class Data
{
std::string name_;
unsigned value_;
} data;
You can't just "send the class" down the wire. If you tried to do something like this:
send(&data, sizeof(data));
...you will end up sending nonsense to the downstream client. `value_` might be received properly, but `name_` surely won't. This is because a `std::string` object consists of much more than just the characters that make up the string. There are also counters, pointers to data buffers, and who knows what else. The characters themselves are probably not even going to be in the memory space indicated by `(&data, &data[sizeof(data)])` -- those characters will be somewhere else entirely. So with the `send` psudocude above, not only do you send a bunch of stuff that the client can't understand, very often you don't even send what they can understand.
Enter serialization. Serialization simply means creating a representation of your data object that can be stored, saved or sent someplace, and reassembled later. You decide what shape this serialization will take. In the case of `data` above, we might decide to serialize like this:
NNNNCCCCCCCC...VVVV
where each character is 1 byte, and:
- N is a 4 character integer, and is the number of characters in `name_` in ASCII representation
- C is N bytes, with each one being one character in `name_`
- V is a 4 character unsigned integer, and is the value in `value_` in ASCII representation
One way to serialize & send `data` above might be something like this (warning: not production quality, untested):
stringstream ss;
ss
<< setw(4) << setfill('0') << right << data.name_.length() << setw(0)
<< data.name_
<< setw(4) << data.value_;
string buf = ss.str();
send(buf.c_str(), buf.length());
Now, instead of trying to send `data`, we're sending a character string that represents `data`. If `data` was created like this:
data.name_ = "foo";
data.value_ = 42;
...then the string that gets sent down the socket will be:
0003foo0042
This can be received by the client and reassembled in to a new `Data` object on the client side that mimics what you have on the server side.
The mapping we used above -- the `NNNNCCCCCCCC...VVVV` -- must be understood by both sides. This is often referred to as a communications protocol.
There are countless protocols and serialization methods used across all application domains. They range from the uber simplistic, like the one I outlined above, to highly compressed and complex, like FIX/FAST. Many libraries provide serialization capabilities that meet the needs of a wide range of applications. Boost.Serialization comes to mind, and I'd suggest you look in to that.
There is much more to this that I've glossed over here. Things like Endianness, security, session control... If you are going to be doing any significant network programming, either on the client side or the server side, you've got quite a bit of learning ahead of you.
Problem
I tried searching everywhere but no luck. Here is my problem: I have a UDP socket, which can send data to any IP address through any port (tested and confirmed working). I read many tutorials, but they were all manipulating `char*[]`, they did not specify how to decrypt it. What I would like to do (pseudo code): Client: ``` Class my_class; send (..., my_class, sizeof(my_class),...) ``` Server: ``` receive (sender, buffer, sizeof (buffer)) and do something like Class my_class = (Class) buffer ``` So I my server can analyze the content of the buffer. But I'm lost with pointers, and all I can send is `char*[]`, so I don't know how to convert back and forth.