Protobuf - .proto文件详解

说明

     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,这样的话解析时必须循环解析。
    process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F1dG9tb2JsaWUw,size_16,color_FFFFFF,t_70)
// 发送端
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

发布了43 篇原创文章 · 获赞 0 · 访问量 3006

猜你喜欢

转载自blog.csdn.net/automoblie0/article/details/101448952
今日推荐