protobuf简介

protobuf简介~~~~~~~~~~~~1. protobuf是什么?protobuf是google出的一个结构化信息传递的工具,用于传递自定的strcut xxx {}内容。可用于在一个机器上的进程间,两台设备各自的进程间,等等。2. protobuf如何用?利用protobuf会生成protobuf编码器和protobuf解码器,两者都依赖protobuf库。a. 使用proto语言写strcut脚本,一般名称为xxx.protob. 用protobuf工具编译脚本生成.c和.h两个文件c. 使用提供函数XXX__get_packed_size()获取msg的sizeXXX__pack()将msg编码《== msg发送 ==》 msg发送端--------------------------------------------------《== msg接收 ==》 msg接收端XXX__unpack()将收到的msg解码XXX__free_unpacked()释放msg资源3. 例子下面是基于protobuf然后采用socket通信的程序。message GenCmd{required uint32 cmd = 1;}message RetVal{required uint32 cmd = 1;required string cmd_str = 2;required sint32 ret = 3;}通过编译protoc-c --c_out=. fct.proto生成fct.pb-c.h和fct.pb-c.c内容略#include#include#include#include#include#include#include "fct.pb-c.h"#define FCT_PORT 0x8888#define MAX_MSG_SIZE 1024int main(int argc, char * argv[]){GenCmd msg = GEN_CMD__INIT; // AMessageRetVal * ret_msg;int socket_client;int recbytes;int sin_size;int len;char buffer[MAX_MSG_SIZE] = {0};int addr_len = sizeof(struct sockaddr_in);struct sockaddr_in s_add;socket_client = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == socket_client){printf("socket fail ! \r\n");return -1;}//printf("socket ok !\r\n");bzero(&s_add, sizeof(struct sockaddr_in));s_add.sin_family = AF_INET;s_add.sin_addr.s_addr = inet_addr("127.0.0.1");s_add.sin_port = htons(FCT_PORT);//printf("s_addr = %#x ,port : %#x\r\n", s_add.sin_addr.s_addr, s_add.sin_port);while (1){printf("input cmd: ");scanf("%s", buffer);while (msg.cmd > 0xfffff){scanf("%s", &msg.cmd);printf("input = %x\n", msg.cmd);sleep(1);}msg.cmd = 0xC2E00000 | msg.cmd;len = gen_cmd__get_packed_size(&msg);bzero(buffer, sizeof(buffer));gen_cmd__pack(&msg, buffer);//fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of messagesendto(socket_client, buffer, MAX_MSG_SIZE, 0, (struct sockaddr *)(&s_add), sizeof(struct sockaddr));recbytes = recvfrom(socket_client, buffer, MAX_MSG_SIZE, 0, (struct sockaddr *)(&s_add), &addr_len);//printf("client recbytes = %x\n", recbytes);if (recbytes > 0){//printf("client recbytes = %s\n", buffer);ret_msg = ret_val__unpack(NULL, recbytes, buffer);if (ret_msg == NULL){fprintf(stderr, "error unpacking incoming message\n");exit(1);}// display the message's fields.printf("client Received: cmd %X, str %s, srtr len %d, ret %d\n", ret_msg->cmd, ret_msg->cmd_str, strlen(ret_msg->cmd_str), ret_msg->ret); // required field// Free the unpacked messageret_val__free_unpacked(ret_msg, NULL);}}close(socket_client);return 0;}#include#include#include#include#include#include#include#include "fct.pb-c.h"#define MAX_MSG_SIZE 1024#define FCT_PORT 0x8888typedef enum{help_cmd = 0,lspci_cmd,last_cmd} command_number;int check_msg_cmd(unsigned int msg_cmd);int help_func(void);int lspci_func(void);int socket_host;struct sockaddr_in s_add;typedef struct {command_number cmd_number;char desc[1024];int (* cmd_func)();} fct_cmd_t;fct_cmd_t fct_cmd_array[] = {{help_cmd, "help cmd", &help_func},{lspci_cmd, "run shell command - lspci", lspci_func},{last_cmd, "the last one command", NULL},};int check_msg_cmd(unsigned int msg_cmd){unsigned int cmd_array_size;unsigned int msg_head;unsigned int msg_num;cmd_array_size = sizeof(fct_cmd_array)/sizeof(fct_cmd_t);msg_head = msg_cmd >> 20;msg_num = msg_cmd & 0xfffff;if (msg_head == 0xC2E){if ((msg_num < cmd_array_size) && (fct_cmd_array[msg_num].cmd_number == msg_num) && (fct_cmd_array[msg_num].cmd_func != NULL)){return 0;}}else{return -2;}return -1;}int help_func(void){int i;int rc = 0;for (i = 0;; i++){if (fct_cmd_array[i].cmd_number != last_cmd){printf("X:\t%s\n", fct_cmd_array[i].cmd_number, fct_cmd_array[i].desc);}elsegoto finish;}finish:return rc;}int lspci_func(void){int rc = 0;rc = system("lspci");return (rc>>8) & 0xff;}int main(int argc, const char * argv[]){GenCmd * msg;RetVal ret_msg = RET_VAL__INIT;struct sockaddr_in local_addr;uint8_t receive_buf[MAX_MSG_SIZE];size_t msg_len;socket_host = socket(AF_INET, SOCK_DGRAM, 0);if (socket_host < 0){printf("Shell socket %d failed", FCT_PORT);return;}local_addr.sin_family = AF_INET;local_addr.sin_addr.s_addr = htonl(INADDR_ANY);local_addr.sin_port = htons(FCT_PORT);if (bind(socket_host, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0){printf("Shell socket bind failed");close(socket_host);return;}if( eMpmnx_Ninja != GetMfaAssemblyType() ){printf("Error: It is not RMX1800 product\n");return -1;}if( MS_MFA_MPMNX != GetMfaBoardType() ){printf("Error: It is not a Meridian_II Card\n");return -2;}InitHardware();InitMfaLowDispatcher();InitDspPostResults();LoadDsp();while (1){struct sockaddr_in raddr;socklen_t addrsize;int readsize;int receive_size;unsigned int msg_cmd;unsigned int msg_head;unsigned int msg_num;int cmd_ret_val = 0;memset(receive_buf, 0, sizeof(receive_buf));addrsize = sizeof(raddr);readsize = recvfrom(socket_host, receive_buf, sizeof(receive_buf), 0, (struct sockaddr *)&raddr, &addrsize);if (readsize > 0){receive_buf[readsize] = '\0';//printf("received %x\n", readsize);// Unpack the message using protobuf-c.msg = gen_cmd__unpack(NULL, readsize, receive_buf);if (msg == NULL){fprintf(stderr, "error unpacking incoming message\n");exit(1);}// display the message's fields.//printf("server Received: %X\n", msg->cmd); // required fieldmsg_cmd = msg->cmd;msg_head = 0xE2C00000;msg_num = msg_cmd & 0xfffff;if (check_msg_cmd(msg_cmd) == -1){printf("msg cmd error, X\n", msg_cmd);msg_num = 0x00000;}cmd_ret_val = fct_cmd_array[msg_num].cmd_func();ret_msg.cmd = msg_head | msg_num;ret_msg.cmd_str = "return";ret_msg.ret = cmd_ret_val;memset(receive_buf, 0, sizeof(receive_buf));readsize = ret_val__get_packed_size(&ret_msg);ret_val__pack(&ret_msg, receive_buf);//printf("%s\n", receive_buf);sendto(socket_host, receive_buf, sizeof(receive_buf), 0, (struct sockaddr *)&raddr, sizeof(raddr));// Free the unpacked messagegen_cmd__free_unpacked(msg, NULL);}}return 0;}编译: gcc -o server server.c fct.pb-c.c -lprotobuf-cgcc -o client client.c fct.pb-c.c -lprotobuf-c生成server和client测试:./ser
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值