2

I'm trying to implement a a program to send a structure over a c++ socket from a client to a server.

What I have so far is working fine on my own computer (Both server and client on my own computer) but I suspect I may have trouble when running the server and client on different computers.

What I have so far is:

struct myStruct
{
    int whatever;
};

//Sender

myStruct obj;
obj.whatever = 123;
char *byteStream = (char *) &obj;

write(socketFD, byteStream, sizeof(myStruct));

//Receiver

char *byteStream = new char[sizeof(myStruct)];
read(socketFD, byteStream, sizeof(myStruct));

myStruct *received = (myStruct *) byteStream;
cout<<received->whatever;

The cout statement at ther receiver prints 123.

Aamir Khan
  • 2,945
  • 2
  • 25
  • 32
  • 2
    A word of warning: If you're using TCP sockets, then the `read` call may receive *less* than what was sent, and you have to read in a loop to receive all. Not very likely with such a small structure, but still something to think about. – Some programmer dude Nov 19 '13 at 08:46
  • 1
    Another word of warning: If you send a structure containing pointers, those pointers will be sent "as is", but what they point to will not be sent. So on the receiving side you then have stray pointers in the structure. Besides, you can barely send pointers from one process to another on a single computer, virtual memory maps and all that, so would work even less sending a pointer to a totally different computer. – Some programmer dude Nov 19 '13 at 08:48
  • The data will contain no pointers. Also I'll be using a UDP socket for this assignment. – Aamir Khan Nov 19 '13 at 08:50
  • 1
    In that case you have to worry about the unreliability of UDP sockets instead, in that packets can be lost, reordered or duplicated. – Some programmer dude Nov 19 '13 at 08:51
  • also read about #pragma pack http://stackoverflow.com/questions/3318410/pragma-pack-effect – mezdejek namejek Nov 19 '13 at 08:54
  • 1
    Actually the assignment's task is to implement reliable data transfer over UDP. ;) The structure I will be sending here will contain information such as sequence number, checksum and the actual message. – Aamir Khan Nov 19 '13 at 08:55
  • 1
    @AamirKhan I would still recommend using network byte ordering – Jonathon Reinhart Nov 19 '13 at 09:12
  • Don't use structs as network protocols. You are introducing dependencies on the compiler, compiler version, surrounding pragmas, compiler options, and hardware, none of which may be the same at the peer, and also introducing semantic restrictions on what can be in the struct (no pointers). Design a wire protocol and write the code to send and receive it, – user207421 Nov 19 '13 at 20:50

4 Answers4

4

This should work on different computers as long as the byte order is the same (e.g., both are PCs).

Reunanen
  • 7,921
  • 2
  • 35
  • 57
  • Really? I was beginning to think that char *byteStream = (char *) &obj; basically assigns the memory address of obj to byteStream and since the memory is common, the receiver prints the correct value. – Aamir Khan Nov 19 '13 at 08:46
  • No, it interprets the pointer to obj as a char* so that this pointer can be passed to write(). – Reunanen Nov 19 '13 at 08:47
  • Thank you so much for your help! Byte order is expected to be the same. – Aamir Khan Nov 19 '13 at 08:48
3

Different systems may use different byte order and structure padding. You need to be sure your structures are packed on both sides. You should generally always send multi-byte integers in network-order (big endian). Convert between byte orders with ntohl and friends.

Community
  • 1
  • 1
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
2

That's fine for now as long as endianness and structure packing are preserved (once you have more than one data member in your struct), but, using sizeof(myStruct) will give you problems when you have data members in your structure that allocate heap memory.

I wouldn't rely on sizeof from the outset. Build a function to get the data size and use that.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

You should seriously consider some kind of serialization library. JSON is very popular and very easy to debug because it is essentially text format. Google protocol buffers are much more efficient, but requires more effort to make it work. There are also other similar libraries like Thrift.

mvp
  • 111,019
  • 13
  • 122
  • 148
  • I have looked at both, but the scope of the assignment doesn't cover Serialization Libraries. I plan to check them out once I develop applications that can run over different platforms, but for now this should be sufficient. – Aamir Khan Nov 19 '13 at 08:53