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.

8
  • 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. Commented Nov 19, 2013 at 8: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. Commented Nov 19, 2013 at 8:48
  • 1
    In that case you have to worry about the unreliability of UDP sockets instead, in that packets can be lost, reordered or duplicated. Commented Nov 19, 2013 at 8:51
  • 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. Commented Nov 19, 2013 at 8:55
  • 1
    @AamirKhan I would still recommend using network byte ordering Commented Nov 19, 2013 at 9:12

4 Answers 4

4

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

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

3 Comments

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.
No, it interprets the pointer to obj as a char* so that this pointer can be passed to write().
Thank you so much for your help! Byte order is expected to be the same.
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.

Comments

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.

Comments

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.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.