Getting segfault due to string data type variable in PROTOBUF server and client communication through sockets on recv end in cpp

前端 未结 1 2002
后悔当初
后悔当初 2021-01-27 10:41

When I am sending a protobuf variable through socket communication on recv end I am trying to display the string variable of protobuf I got segmentation in this remaining Data t

相关标签:
1条回答
  • 2021-01-27 11:04

    Your problem is here:

    star pkt;
    recv(csd,&pkt,sizeof(pkt),0);
    

    and here:

    star pkt;
    pkt.set_name("Pratap");
    cout<<"Send Data without help of another variable....\n";
    send(sd,&pkt,sizeof(pkt) ,MSG_CONFIRM);
    

    You can't receive/send the star instance directly without de/serializing it from/to protobuf wire format first. Have a look at the ParseFrom SerializeTo methods of the protobuf::MessageLite class.

    The best way is to send the length of the serialized message first in a fixed format (e.g. a uint32_t in network byte order). Then the receiver can read this first and allocate a buffer of the appropriate size before receiving the serialized message that is send afterwards.

    UPDATE:
    Try s.th. like this:

    Sender.cpp

    star pbMsgObj;
    pbMsgObj.set_name("Pratap");
    
    std::string pkt;
    pbMsgObj.SerializeToString(&pkt); // Serialize the message object to 
                                      // protobuf wire format.
    uint32_t msgLength = pkt.size();
    uint32_t sndMsgLength = htonl(msg_length); // Ensure network byte order
    
    send(sd,&sndMsgLength ,sizeof(uint32_t) ,MSG_CONFIRM); // Send the message length
    send(sd,pkt.c_str() ,msgLength ,MSG_CONFIRM); // Send the message data 
    

    Receiver.cpp

    star msgObject;
    uint32_t msgLength;
    recv(csd,&msgLength,sizeof(uint32_t),0); // Receive the message length
    msgLength = ntohl(msgLength); // Ensure host system byte order
    
    std::vector<uint8_t> pkt; // Allocate a receive buffer
    pkt.resize(msgLength,0x00);
    
    recv(csd,&(pkt[0]),msgLength,0); // Receive the message data
    std::string tmp;
    tmp.assign(&(pkt[0]),pkt.size()); // Convert message data to a string
    
    msgObject.ParseFromString(tmp); // Deserialize the message object from
                                    // protobuf wire format.
    

    NOTE:
    De-/Serializing from/to a unique, efficient wire format used with various language bindings is the whole point of google protocol buffers.

    For twiddling out the bits of possible sender/receiver patterns, instead of creating 'raw' sockets you might find 0MQ being a useful framework. Anyway listen to good advice(!): Keep message (payload) format and send/recv behavior as separate as possible.

    0 讨论(0)
提交回复
热议问题