说明
proto文件扩展名称为".proto",可以使用import包含另一个.proto文件。
字段限制
required —— 必须赋值的字符
optional —— 可有可无的字段,可以使用[default = xxx]配置默认值
repeated —— 可重复变长字段,类似数组
类型
- 系统默认值:
string默认为空字符串;
bool默认为false;
数值默认为0;
enum默认为第一个元素
举例
- 小例
如下,"proto2"语法类型、VsQtProtobuf包名、Persion为消息名、消息内部定义了4个带有默认值得项 - 1个必填和3个选填、性别枚举、消息Grade和Language。
注意:嵌套的Grade和Language声明方式不一样。在代码里解析也不一样。首先Grade声明的是optional那么直接按常规使用即可;Language声明方式为repeaed,这样的话解析时必须循环解析。
// 发送端
void ProtobufTest_A::on_sendButton_A_clicked()
{
// 单播
// qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677);
//组播ip地址范围:224.0.0.0-239.255.255.255
//qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677);
//广播
//qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(), QHostAddress::Broadcast, 6677);
// 序列化前初始值
VsQtProtobuf::Persion protobufTest;
protobufTest.set_id(ui.port_A->text().toInt());
VsQtProtobuf::Persion::Language *language = protobufTest.add_language();
// 获取长度
unsigned short protobufTestLength = protobufTest.ByteSize() + 1;
// 存储序列化buf
char *buf = nullptr;
buf = new char[protobufTestLength];
memset(buf, 0, protobufTestLength);
// 序列化
protobufTest.SerializeToArray(buf, protobufTestLength);
// udp发送
UdpSocket_A->writeDatagram(buf, protobufTestLength, QHostAddress(ip_B), port_B);
// 释放序列化buf
if (buf)
delete buf;
buf = nullptr;
}
// 接收端
void ProtobufTest_B::readyRead()
{
QByteArray array;
array.resize(UdpSocket_B->bytesAvailable());
if (array.size())
{
UdpSocket_B->readDatagram(array.data(), array.size());
VsQtProtobuf::Persion protobufTest;
protobufTest.ParseFromArray(array.data(), array.size());
ui.receiveTxt_B->append("id:\t" + QString::number(protobufTest.id()));
ui.receiveTxt_B->append("name:\t" + QString(protobufTest.name().c_str()));
ui.receiveTxt_B->append("age:\t" + QString::number(protobufTest.age()));
if (::VsQtProtobuf::Persion_Sex::Persion_Sex_man == protobufTest.sex())
ui.receiveTxt_B->append("sex:\t"+QString::fromLocal8Bit("男"));
else if (::VsQtProtobuf::Persion_Sex::Persion_Sex_woman == protobufTest.sex())
ui.receiveTxt_B->append("sex:\t" + QString::fromLocal8Bit("女"));
else if (::VsQtProtobuf::Persion_Sex::Persion_Sex_taiguo == protobufTest.sex())
ui.receiveTxt_B->append("sex:\t" + QString::fromLocal8Bit("男女"));
ui.receiveTxt_B->append("address:\t" + QString(protobufTest.address().c_str()));
VsQtProtobuf::Persion::Grade grade =protobufTest.grade();
ui.receiveTxt_B->append("grade-chinese:\t" + QString::number(grade.chinese()));
ui.receiveTxt_B->append("grade-english:\t" + QString::number(grade.english()));
// 声明方式"repeaed"的解析过程
int indexs = protobufTest.language_size();
for (unsigned int index = 0; index < indexs; ++index)
{
bool language_chinese = protobufTest.language(index)._chinese();
if (language_chinese)
ui.receiveTxt_B->append("language-chinese:\tyes");
else
ui.receiveTxt_B->append("language-chinese:\tno");
bool language_english = protobufTest.language(index)._english();
if (language_english)
ui.receiveTxt_B->append("language-english:\tyes");
else
ui.receiveTxt_B->append("language-english:\tno");
ui.receiveTxt_B->append("\n");
}
}
}
- 结果
源码
关注
微信公众号搜索"Qt_io_"或"Qt开发者中心"了解更多关于Qt、C++开发知识.。
笔者 - jxd