views:

350

answers:

4

Hi,

I am trying to send a proto over a socket, but i am getting segmentation error. Could someone please help and tell me what is wrong with this example?

file.proto

message data{  
    required string x1 = 1;
    required uint32 x2 = 2;
    required float x3 = 3;
}

xxx.cpp

    ...
    data data_snd, data_rec;

    //sending data to the server
    if (send(socket, &data_snd, sizeof(data_snd), 0) < 0) {
       cerr << "send() failed" ;
       exit(1);
     }  

     //receiving data from the client
     if (recv(socket, &data_rec, sizeof(data_rec), 0) < 0) {
        cerr << "recv() failed";
        exit(1);
     }  

Thanks for help and replies-

+1  A: 

For one thing, you're assuming that a single call to recv will retrieve all the data. More importantly though, you're not going through the serialization / deserialization code - you're just reading from the network and putting the bytes directly into the object. You should be using the stream-based APIs in Protocol Buffers to write and read the data.

See the Protocol Buffers C++ tutorial for more details - that gives an example of saving to disk, but I expect that the network version would be similar, just with a different stream.

Jon Skeet
thanks for reply! could you please provide a small exp ...
make
@make: No, I'm afraid I don't have enough C++ experience to do a decent job of it - but you should be able to adapt the code from the tutorial without too much difficulty.
Jon Skeet
@jon-skeet, thanks! ... this is the first time that I am trying to work with serialization / deserialization . Any help would be very appreciated. thanks again!
make
+1  A: 

Give more details about where it segfaults and how you manage the connection between server and client.

Use a debugger and print the backtrace, it will help ...

neuro
thanks for reply! the segfault just when the server is receiving data ...
make
@make: you are welcome. The answers do not really explain your segfault. The recv call seems correct and should not have segfaulted as is. I suspect your code is more complex than your snippet. Good luck with your app.
neuro
@neuro Thanks for your message. Actually there were serialization and deserialization codes missing and this is why I got sementation faults. and after I received a message from @jespere, I successed to make my codes working. So, thanks to all and it was really nice to share your experiences with me......
make
A: 

See this article How to send objects from Java to .Net that shows how to serialize complex structures over the wire. You can use the same techniques to serialize using C/C++.

Use htons() and htonl() to serialize integers/shorts on the wire. Then you can use ntohs() and ntohl() to deserialize from the wire onto the C/C++ structure.

feroze
thanks for the reply> unfortunately it isn't what I am trying to do ... thanks again
make
+3  A: 

You're not supposed to write the protobuf object itself to the socket. Use the SerializeXXX family of methods to get a sequence of bytes which you can write to the socket.

std::string buf;
data.SerializeToString(&buf);
// now you can write buf.data() to the socket
JesperE
@jespere, thanks a lot for youe reply. just a question please. At receiving, should I deserialize also? is this similar to serialization or not? Please help and thanks again!
make
When deserializing, you use the ParseFromString method (or one of its relatives).
JesperE
Thanks a lot again! I finaly made it ... just another question please.you mentioned to use buf.data(). does it similar to buf.c_str() or not? For the size of data to write to socket, can I use sizeof(buf.data()) ... i.e., send(socket,buf.data(), sizeof(buf.data()), 0) or not? Thanks again for help
make
See here for a description of data vs. c_str. http://www.cplusplus.com/reference/string/string/data/
JesperE
thanks a lot again for your help
make