4

I am building a UDP chat app. Is it safe sending C struct over c socket and on the other end memset received data? All data in struct is nullpaded with memset, so I assume the size of the struct is always constant. What problems may I encounter?

How are more experienced programmers approaching this?

1

4 Answers 4

6

Yes it is safe BUT we should caveat this first. You may run into a problem if you are passing it between disparate platforms and then you need to worry about byte ordering/packing (amongst a host of other issues possibly). That being said, if you don't know how to do any of this, then it is not safe to assume that you will reliably receive the struct in the same order you sent it.

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

10 Comments

That's potentially a pretty serious concern!
I believe PPC and MIPS are two platforms with different byte orders. You can often find these chips in game systems and networking equipment, like WiFi routers.
Different packing is easy to find: 32 and 64 bit systems will often pack integers differently.
You started your answer with a lie, then followed it up with a bootnote about the very serious issues that render your first sentence nonsense.
@Tomalak: It is safe, if you follow the rules. Driving can be unsafe if you don't wear your seatbelt.
|
5

However you do it, unit test the hell out of it. Compilers and platforms vary a lot on these points, so don't ever assume blindly that it is consistent.

Compilers may change struct alignment at their whim (for performance reasons, for example). Asking for some restrictions are generally compiler specific, though this one is supported by MSVC and gcc (through an extension)

#pragma pack(push, 1) struct Foo { // .. }; #pragma pack(pop) 

This forces it to align on 1 byte boundaries, so no booleans.

If you want to be fully compliant, then serialize each field yourself. It really isn't all that much work.

You will also have to deal with endianness, as mentioned by others.

5 Comments

In the new C++11 standard, this #pragma pack extension will not needed anymore, as we have the alignas specifier :)
That is really good news. I always found a lot of this sort of stuff under supported.
Yeah, but you'll have to wait a while though. Even though compilers already implement a lot of big C++11 features, no compiler that I know of implements alignas yet :(
alignas will only get you part way there when it comes to cross platform alignment support. alignof(T) flexible enough to let you specify alignment for objects you're going to typecast, but if your architecture aligns T wierdly, then anything aligned using alignof(T) will also be aligned wierdly when you want to send it over the network.
makes no sense, everything is at least 1byte-aligned
3

All data in struct is nullpaded with memset, so I assume the size of the struct is always constant.

This doesn't make a lot of sense. Objects always have a fixed size. "Nullpadding with memset" has nothing to do with it.

Is it safe sending C struct over c socket and on the other end memset received data?

No, not really.

Better to consider sending "data" rather than the exact, byte-wise, physical contents of an object in your memory.

What problems may I encounter?

  • Member padding
  • Data alignment
  • Type sizes
  • Endianness
  • Indirection — pointers to data rather than the data itself

How are more experienced programmers approaching this?

Best do serialisation properly.

Create a data format that your application will recognise no matter what machine it's on, and use that to represent your chat data.

  1. Sometimes for efficiency you have to design a binary format, and use clever, robust techniques to deserialise the information properly on the target machine, taking the above listed considerations into account.

  2. However, for simple work, you can just use human-readable text format. Can't really go wrong with that.

2 Comments

+1 I think this a great answer, becuase it explains all of the problems clearly. OTOH, sending a struct over the wire definitely can be done if you are careful and have a plan for dealing with each of the problems that you might encounter, and I do think that C was designed to allow that sort of thing if you know how to do it properly.
@Ken: I don't think that C was, but some of the implementations that follow its mandates may be.
1

You have to be careful that your struct doesn't contain pointers (like char* strings). That applies when you store a std::string inside the struct as well, because the std::string has a pointer inside of it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.