send/recive struct
lets say I have a struct with different datatypes:
struct stuff
{
unsigned int somevar1;
int somevar2;
std::string somevar3;
bool somevar4;
};
I want to send this between computers. I have earlier used async sockets before and sent/recived text (char bytes). The problem is how I can merge this struct into a packet, and pack it out into a struct when recived. Any ideas?
Unfortunately your structure contains a string, and, I really never use std::string but it probably uses a pointer, which would be completely useless on the receiving end. The point points to the string data, so you're probably going to have to do some extra work to send the string.
Here's what you normally do with a self contained structure.
Now, I put the "char fixedlengthstring[32];" in there just as an alternate solution to your problem. This way the string is all contained within the struct 'stuff', but can only be 32 bytes long. You may want longer strings. I think you probably want to be able to send variable length strings, so I'll help there too.
When all is said and done, you probably want to make a send function, or pack function, a part of that structure, or something more contained than what i just did. There are other ways too. You can send the length of the string, and omit the null char if you want. Make sure you unpack the buffer on the other end in a similar way.
If you are using a self-contained struct, as in my first example, you can just do something like this:
And if you use structs with dynamically stored strings or other data, you'll have to manually allocate them on the receiving end, and copy the sections into their proper locations.
I hope this helps some, and.. sorry for crap lol
[edited by - n0ob on April 12, 2004 12:39:54 AM]
Here's what you normally do with a self contained structure.
struct stuff{ int var1; bool var2; char fixedlengthstring[32];};stuff sendMe;Send( (char*) &sendMe, sizeof(sendMe) ); //your send function, that takes length as a parameter
Now, I put the "char fixedlengthstring[32];" in there just as an alternate solution to your problem. This way the string is all contained within the struct 'stuff', but can only be 32 bytes long. You may want longer strings. I think you probably want to be able to send variable length strings, so I'll help there too.
struct stuff{ std::string var1; char * var2; int var3;};stuff sendMe;//example packing code for your send function, and the experts cringechar sendBuffer[MAX_SEND_LENGTH] = {0};char * curIdx = sendBuffer;memcpy(curIdx, sendMe.var1.GetString(), sendMe.var1.GetLength());curIdx += sendMe.var1.GetLength()+1; //account for null char , if string doesn't already//alternate string packingstrcpy(curIdx,sendMe.var2);curIdx += strlen(sendMe.var2)+1; // account for null char again((int*)curIdx) = sendMe.var3; // or whatever syntax works here, sorry
When all is said and done, you probably want to make a send function, or pack function, a part of that structure, or something more contained than what i just did. There are other ways too. You can send the length of the string, and omit the null char if you want. Make sure you unpack the buffer on the other end in a similar way.
If you are using a self-contained struct, as in my first example, you can just do something like this:
struct stuff{...};stuff recvMe;Receive((char*)&recvMe, sizeof(recvMe)); // your receive function
And if you use structs with dynamically stored strings or other data, you'll have to manually allocate them on the receiving end, and copy the sections into their proper locations.
I hope this helps some, and.. sorry for crap lol
[edited by - n0ob on April 12, 2004 12:39:54 AM]
it help some, but I still need to know how to send a string...
isnt it possible to send a int with the size of the string, and then send the chars raw byte by byte? in istream you can use reinterpet_cast or something to make raw bytes become a struct. is this possible to use with winsock sending an reciving?
isnt it possible to send a int with the size of the string, and then send the chars raw byte by byte? in istream you can use reinterpet_cast or something to make raw bytes become a struct. is this possible to use with winsock sending an reciving?
Hello invictus,
Well if you need to send the struct you need to byte stream or flatten out the structure into a stream of bytes with no padding.
compilers add padding to structure/classes for alignment of data memebrs.
In you example I would do the following.
First reorder your struct try to put things that can''t change size first in the struct, so move string after bool.
struct stuff
{
unsigned int somevar1; // 4 bytes
int somevar2; // 4 bytes
bool somevar4; // 1 byte most like
std::string somevar3; // 0 to any number of bytes
};
Next create a char buffer of the size of all the member size are.
char buf = new char[9+(string size + 1 for null)];
Next copy in the data members.
This can be done by memcpy, or use strstream, or stright byte for byte copy by pointer.
The idea is first 4 byte of buf have somevar1 data, next 4 has somevar2 9 byte has the bool value and then the rest of but byte 10 on has the string''s data in it plus the null.
On the reciving side you put first 4 byte of buf into somevar1 next 4 into somevar2 9 byte into bool and then treat the 10 byte as begining char* and assign to string.
If you need to go between different endianness system might want to use network order byte stream (ie big endian), then you would need to swap byte data members somevar1 and somevar2 if you on a little endian system.
If sending by tcp send size of buf first then the buf.
size of string is size sent - 9 bytes.
On recv side once you past 9 bytes (somevar1, somevar2, and bool) your at the start of the string data with null.
By udp you know the size at reading the udp message size of sting is size read - 9 bytes.
Just some ideas to look at.
Lord Bart
Well if you need to send the struct you need to byte stream or flatten out the structure into a stream of bytes with no padding.
compilers add padding to structure/classes for alignment of data memebrs.
In you example I would do the following.
First reorder your struct try to put things that can''t change size first in the struct, so move string after bool.
struct stuff
{
unsigned int somevar1; // 4 bytes
int somevar2; // 4 bytes
bool somevar4; // 1 byte most like
std::string somevar3; // 0 to any number of bytes
};
Next create a char buffer of the size of all the member size are.
char buf = new char[9+(string size + 1 for null)];
Next copy in the data members.
This can be done by memcpy, or use strstream, or stright byte for byte copy by pointer.
The idea is first 4 byte of buf have somevar1 data, next 4 has somevar2 9 byte has the bool value and then the rest of but byte 10 on has the string''s data in it plus the null.
On the reciving side you put first 4 byte of buf into somevar1 next 4 into somevar2 9 byte into bool and then treat the 10 byte as begining char* and assign to string.
If you need to go between different endianness system might want to use network order byte stream (ie big endian), then you would need to swap byte data members somevar1 and somevar2 if you on a little endian system.
If sending by tcp send size of buf first then the buf.
size of string is size sent - 9 bytes.
On recv side once you past 9 bytes (somevar1, somevar2, and bool) your at the start of the string data with null.
By udp you know the size at reading the udp message size of sting is size read - 9 bytes.
Just some ideas to look at.
Lord Bart
![](smile.gif)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement