2010-03-12 3 views
2

Я пытаюсь отправить proto через сокет, но я получаю ошибку сегментации. Может ли кто-нибудь помочь и рассказать мне, что не так с этим примером?как отправлять классы, определенные в .proto (протокольные буферы) через сокет

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); 
    } 

Спасибо за помощь и replies-

ответ

6

Вы не должны писать сам объект Protobuf к гнезду. Используйте семейство методов SerializeXXX, чтобы получить последовательность байтов, которую вы можете записать в сокет.

std::string buf; 
data.SerializeToString(&buf); 
// now you can write buf.data() to the socket 
+0

@jespere, спасибо большое за ответ. только вопрос пожалуйста. При приеме, следует ли и десериализовать? это похоже на сериализацию или нет? Пожалуйста, помогите и еще раз спасибо! – make

+0

При десериализации вы используете метод ParseFromString (или один из его родственников). – JesperE

+0

Еще раз спасибо! Я окончательно сделал это ... просто еще один вопрос. Вы упомянули использовать buf.data(). похоже ли это на buf.c_str() или нет? Для размера данных, которые нужно записать в сокет, могу ли я использовать sizeof (buf.data()), т. Е. Отправить (socket, buf.data(), sizeof (buf.data()), 0) или нет? Еще раз спасибо за помощь – make

5

С одной стороны, вы предполагая, что один вызов recv извлечет все данные. Что еще более важно, однако, вы не проходите код сериализации/десериализации - вы просто читаете из сети и помещаете байты непосредственно в объект. Вы должны использовать потоковые API в буферах протоколов для записи и чтения данных.

Для получения более подробной информации см. Protocol Buffers C++ tutorial - это пример сохранения на диск, но я ожидаю, что сетевая версия будет похожа, просто с другим потоком.

+0

благодарит за ответом! не могли бы вы предоставить небольшой exp ... – make

+0

@make: Нет, боюсь, у меня недостаточно опыта на C++, чтобы сделать достойную работу, но вы также сможете адаптировать код из учебника без много трудностей. –

+0

skeet, спасибо! ... это первый раз, когда я пытаюсь работать с сериализацией/десериализацией. Любая помощь будет очень оценена. еще раз спасибо! – make

1

Дайте более подробную информацию о том, где это происходит, и как вы управляете соединением между сервером и клиентом.

Используйте отладчик и распечатать трассировку, это поможет ...

+0

благодарю вас за ответ! segfault, только когда сервер получает данные ... – make

+0

@make: добро пожаловать. Ответы действительно не объясняют ваш segfault. Обратный вызов кажется правильным и не должен быть прерван, как есть. Я подозреваю, что ваш код более сложный, чем ваш фрагмент. Удачи с вашим приложением. – neuro

+0

Спасибо за сообщение. На самом деле отсутствовали коды сериализации и десериализации, и именно поэтому я получил ошибки секционирования. и после того, как я получил сообщение от @jespere, мне удалось заставить мои коды работать. Итак, спасибо всем, и было очень приятно поделиться с вами своими впечатлениями ...... – make

Смежные вопросы