protobuf string类型_由于PROTOBUF服务器中的字符串数据类型变量和通过cpp的recv端上的套接字进行客户端通信而导致段错误...

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 type other than String they are working fine but string variable case I got segmentation How can I over come in Protobuf string datatype segmentation fault other than we have any other data type for store the string data type.

I create a example.proto with in string variable name is there

I am compile example.proto with protoc compiler (protoc example.proto --cpp_out )

it create two files two files example.pb.h, example.pb.cc

By using these files I create a test_server.cpp and test_client.cpp

And compile it. but at the time of both programms runing I sent a protobuf variable on recv side it give segmentation fault due to trying to display string variable.

How can I solve this problem?

example.proto

package data;

message star

{ optional string name=1; }

server.cpp

#include

#include

#include

#include

#include

#include

#include

#include"example.pb.h"

#include"example.pb.cc"

int main()

{

int sd,csd;

sd=socket(AF_INET, SOCK_STREAM,0);

perror("socket");

sockaddr_in ser,cli;

ser.sin_family=AF_INET;

ser.sin_port=htons(7878);

ser.sin_addr.s_addr=inet_addr("X.Y.Z.A");

bzero(ser.sin_zero, 8);

size_t s=16;

if(bind(sd,(struct sockaddr *)&ser, s)==-1)

cout<

else

cout<

if((csd=accept(sd,(struct sockaddr *)&cli, &s))==-1)

cout<

else

cout<

star pkt;

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

cout<

close(sd);

close(csd);

}

client.cpp

#include

#include

#include

#include

#include

#include

#include

#include"example.pb.h"

#include"example.pb.cc"

int main()

{

int sd;

sd=socket(AF_INET, SOCK_STREAM,0);

perror("socket");

sockaddr_in ser;

ser.sin_family=AF_INET;

ser.sin_port=htons(7878);

ser.sin_addr.s_addr=inet_addr("X.Y.Z.A");

bzero(ser.sin_zero, 8);

if(connect(sd,(struct sockaddr *)&ser, 16)==-1)

cout<

else

cout<

star pkt;

pkt.set_name("Pratap");

cout<

send(sd,&pkt,sizeof(pkt) ,MSG_CONFIRM);

close(sd);

}

解决方案

Your problem is here:

star pkt;

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

and here:

star pkt;

pkt.set_name("Pratap");

cout<

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 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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值