Sign in to follow this  

So, I want to send a struct...

This topic is 3765 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Yes, yes... you've heard this question before. I've read the FAQ... and almost every tutorial linked to from this site or that appeared in the first 10 pages of a Google search... I've seen methods for byte packing into network byte order... and methods for writing everything to string and decoding again... and methods for sending unions... but which is best for my situation? I'm under severe time constraints, so I don't have time to try them all (I have a bunch of students waiting to get access to this code... if I hold them up much longer fiddling around with it, it's going to affect their assessment and that's not fair). My scenario: client and server running on same machine... I need to send structs of known (but different) sizes back and forth between client and server (application data... basically server state information one way and client commands the other, as with most games)... I will typically need to send a variable number of structs after a fixed number of iterations of client and server... I've written the server and skeleton client app... students fill in some functionality details in client... (they don't get server code, just exe)... Presently I have basic string based communication going between client/server, but need to extend this to data... (I'm using a single comms socket, but considering using two one-way sockets)... Time is of the essence... data must be transmitted and decoded as fast as possible (client and server are real-time applications... or at least intended to simulate a real time system)... If, for example, I want to send send two possible types structs from the server to the client, e.g.:
struct msg1_type { enum, float, float, vector_2 };
struct msg2_type { vector_2, vector_2, float, float, float,..., bool, bool }; // etc

and I want to send N of the first type and 1 of the second every cycle (N varies per cycle)... what would your sagely advice be? Pack them all into one large packet of varying length? Send them individually by treating them as a byte array (via a union)? I guess I'm just looking for advice on which way to proceed so I don't waste more time (I've already spent a good week or more reading and I don't feel I'm any closer to knowing which is the right way to go). What I'd like to end up with is something that acts like a stream that hides the networking... (either a single stream with insertion and extraction, or two streams... one for sending/inserting and the other for receiving/extracting). Thoughts? Comments? Please try to be constructive. If you need more information about the application, just ask. It's not top secret, but I'm not certain as to what is relevant so I don't want to paste 50 files here. 8) Cheers and thanks, Timkin (the networking noob)

Share this post


Link to post
Share on other sites
I'd probably send the entire thing in one big packet, especially if you are sending this over TCP. Just write the number of type1 structs, then all of them, followed by the type2.

Share this post


Link to post
Share on other sites
yeah what Driv3MeFar said. Works if you always knows that order of the packets, ie that msg_type1 is always followd by msg_type2. So this only works on a relible protocol. Another popular way to do this is to begin each packet with an byte that represents the datatype of the packet. Then you wouldn't have to order them like that. Just peek at the first byte, and then read the size of that datatype to the correct struct.

Ie:


struct msg_type1
{
char id; // = MSG_TYPE1 for this packet
bool i;
float j;
int d;
}


struct msg_other_t
{
char id; // = MSG_SOME_OTHER_PACKET_TYPE for this packet
bool b[43];
}

----------------------

char peek_byte;

while(socket.peek(peek_byte, 1)) // peek 1 byte
{

if(MSG_TYPE1 == peek_byte)
{
msg_type1_t msg_type1;
socket.read((char*)&msg_type1);
}
else if(MSG_SOME_OTHER_PACKET_TYPE == peek_byte)
{
msg_other_t msg_other;
socket.read((char*)&msg_other);
}
}

Share this post


Link to post
Share on other sites
Like peter_b said, send a 'type' byte first before any struct. Now you know what struct to expect so you can read X number of bytes as needed to fill the struct. To send you can just do:

send (Socket, Struct, sizeof(struct), 0);

If you want to be endian-safe however, you will need to convert all shorts and longs (and maybe floats, not sure) to network byte order first; be it constructing a new struct, or converting the struct into a byte buffer and sending that.

--Zims

Share this post


Link to post
Share on other sites
Take a look at this, it'll likely be a better solution. Just be careful when passing pointers.

It's basically a lock-less IPC queue, with throughput essentially identical to that of memcpy.

Share this post


Link to post
Share on other sites
Thanks for the responses... I probably didn't make it clear enough in my initial post... but obviously I'd send structs packed into an application communication protocol such as a HEADER+PAYLOAD packet scenario, with header including fields indicating payload type and size. My question was more about the right approach... I guess I'll just follow the old 'pretend its a byte array' method and deal with any subsequent issues later (eek, did I just say that!?).

As for the IPC suggestion...thanks, but I don't have enough time to get my head around that at the moment... perhaps for next years revision! ;)

Thanks,

Timkin

Share this post


Link to post
Share on other sites
Quote:
Original post by dvogel
If you know that the server and client are always on the same machine, you could store the structs in shared memory.


I think the point is to demonstrate network programming (possibly shown using the loopback), not an actual program. That is just a guess from reading the OP however.

Share this post


Link to post
Share on other sites

This topic is 3765 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this