Linuxc++socket 接收protobuf并解码的demo,每一条消息由消息头、消息体组成。消息采用单字节对齐方式。本接口规范中的所有整数类 型字段都采用低字节序(LITTLE-ENDIAN)编码方式。如用 java 开发客户端接收程序, 需要转整数字段换字节序。
时间: 2024-03-05 17:47:55 浏览: 89
这里提供一个简单的示例代码,用于接收 protobuf 消息并解码,假设消息头的长度为 4 字节、包含消息体长度和消息类型两个字段,消息体为 protobuf 格式:
```c++
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <google/protobuf/message.h>
using namespace std;
using google::protobuf::Message;
#define BUFSIZE 1024
// 解码消息头
struct MsgHeader {
int32_t length; // 消息体长度
int32_t type; // 消息类型
};
// 接收数据
int recvData(int sock, char* buffer, int length) {
int recvLen = 0;
while (recvLen < length) {
int ret = recv(sock, buffer + recvLen, length - recvLen, 0);
if (ret < 0) {
return -1;
}
recvLen += ret;
}
return recvLen;
}
// 接收并解析消息
bool receiveMessage(int sock, Message* message) {
// 接收消息头
MsgHeader header;
if (recvData(sock, (char*)&header, sizeof(header)) != sizeof(header)) {
return false;
}
// 转换字节序
header.length = ntohl(header.length);
header.type = ntohl(header.type);
// 接收消息体
char body[BUFSIZE];
if (recvData(sock, body, header.length) != header.length) {
return false;
}
// 解码消息体
if (!message->ParseFromArray(body, header.length)) {
return false;
}
return true;
}
```
使用示例:
```c++
// 创建 TCP 客户端 socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
// 连接服务器
struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(8080);
connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
// 接收并解析消息
MyMessage msg;
if (receiveMessage(sock, &msg)) {
// 处理消息
...
}
// 关闭 socket
close(sock);
```
阅读全文