C++ How can I send an object via socket?

16,799

Solution 1

It's impossible to send objects across a TCP connection in the literal sense. Sockets only know how to transmit and receive a stream of bytes. So what you can do is send a series of bytes across the TCP connection, formatted in such a way that the receiving program knows how to interpret them and create an object that is identical to the one the sending program wanted to send.

That process is called serialization (and deserialization on the receiving side). Serialization isn't built in to the C++ language itself, so you'll need some code to do it. It can be done by hand, or using XML, or via Google's Protocol Buffers, or by converting the object to human-readable-text and sending the text, or any of a number of other ways.

Have a look here for more info.

Solution 2

you can do this using serialization. This means pulling object into pieces so you can send these elements over the socket. Then you need to reconstruct your class in the other end of connection. in Qt there is QDataStream class available providing such functionality. In combination with a QByteArray you can create a data package which you can send. Idea is simple:

Sender:

QByteArray buffer;
QDataStream out(&buffer);
out << someData << someMoreData;

Receiver:

QByteArray buffer;
QDataStream in(&buffer);
in >> someData >> someMoreData;

Now you might want to provide additional constructor:

class blocco
{
    public:
        blocco(QDataStream& in){
            // construct from QDataStream
        }

        //or
        blocco(int id, char* data){
            //from data
        }
        int ID;
        char* data;


        blocco(int id);
};

extended example

Share:
16,799
rosekarma
Author by

rosekarma

Updated on October 24, 2022

Comments

  • rosekarma
    rosekarma over 1 year

    I have a question for you.

    I have this class:

    `

    #define DIMBLOCK 128
    #ifndef _BLOCCO_
    #define _BLOCCO_
    
    class blocco
    {
        public:
            int ID;
            char* data;
    
    
            blocco(int id);
    };
    
    #endif
    
    
    
    
    blocco::blocco(int id)
    {
        ID = id;
        data = new char[DIMBLOCK];
    }
    

    `

    and the application has a client and a server. In the main of my server I instantiate an object of this class in this way: blocco a(1);

    After that I open a connection between the client and the server using sockets. The question is: how can I send this object from the server to the client or viceversa? Could you help me please?

  • rosekarma
    rosekarma over 10 years
    So, it isn't possible to do something like that: ret = send(sock, reinterpret_cast<void*>(&a), sizeof(blocco),0);?
  • Jeremy Friesner
    Jeremy Friesner over 10 years
    No. That won't work for a number of reasons... for one, it won't follow pointers (e.g. the receiver of a blocco that was sent that way would receive the value of the (data) pointer rather than the characters that (data) points to, which wouldn't be useful). It also doesn't correctly handle padding and endian-ness issues.
  • David Schwartz
    David Schwartz about 7 years
    @rosekarma What good would that do? How would you write code to receive the data given that you would have literally no idea what bytes you had sent to it. To write code to receive the data, the first thing you'd need to know is how many bytes encode the ID. But you don't even know that -- and, worse, it will change if you change the compiler, platform, etcetera.
  • Jeremy Friesner
    Jeremy Friesner about 7 years
    If you want to see why that approach doesn't work, try printing out the character string pointed to by the 'data' member item of the 'received' blocco object after recv() returns. You'll find that the string did not get transferred across, and you'll either print out garbage or (more likely) your program will crash when it tries to dereference data's pointer, which is set to point to an address that was valid in the sender's memory-space but not in the receiver's memory-space.
  • Admin
    Admin about 7 years
    I implemented this on my macbook and ran both the client and server on the same machine. I was successfully able to access the data, and did not face any crashes/garbage value issue. Maybe if I try to do this across multiple systems with differing endian systems I'll have a problem?
  • Admin
    Admin about 7 years
    I get your point now, if I have pointers I'll face these issues. Although if I have a string (which I did in my code), then I won't face these issues.
  • Jeremy Friesner
    Jeremy Friesner about 7 years
    Most string classes contain a pointer internally, so you'll likely still face that issue. Even if you didn't, though, you'd still face the other issues (endian-ness differences, word-size differences, struct-padding differences) except under specific circumstances (i.e. except when both the sending and the receiving program were compiled for the same CPU architecture and the same OS, using the same compiler with the same settings)