gpt4 book ai didi

c++ - 在 C++ 中解析基于 TCP 的 TLV 协议(protocol)的问题

转载 作者:太空宇宙 更新时间:2023-11-04 11:35:49 24 4
gpt4 key购买 nike

我正在尝试通过 TCP 从 python 客户端发送 Protocol Buffer 并使用 C++ 服务器接收 Protocol Buffer 来实现 (T)LV 协议(protocol)。

我的代码大致是这样的:

char* buffer[RCVBUFSIZE];
int recvsize= 0;
// Filling my buffer with as much as possible.
while(true) {
if(recvsize == RCVBUFSIZE) {
break;
} else if(recvsize+= recv(sock, buffer+recvsize, sizeof(buffer)-recvsize, 0) < 1) {
break;
}
}
//Parsing LV protocol
while(true) {
unsigned short protosize= 0;
//Copy first two bytes into protosize
memcpy((char *) &protosize, buffer, sizeof(unsigned short));
if(protosize == 0) { break; } // Protocol indicates EOM be setting length to "0"
void* protomsg[protosize];
memcpy(protomsg, buffer+sizeof(unsigned short), protosize);
int msglength= sizeof(unsigned short)+protosize;
//Now I'll move the whole buffer to the left so that I don't have to keep track of where I'm at.
memmove(buffer, buffer+msglength, RCVBUFSIZE-msglength);
protoMsg pm;
if(!pm.ParseFromArray(protomsg, protosize)) { break; } // Parsing failed.
// Do stuff with parsed message.
}

现在我有几个问题:

  • 接收消息的 while 循环永远不会终止。我怀疑当不再有任何数据时 recv 调用会阻塞,而我预计它会返回错误。我找到了 select 函数来检查是否有东西要读。我会尝试一下。但是当我只调用一次 receive 来跳过这个问题时(收到的消息大约有 10 个字节,所以我希望在一次调用中收集所有消息。)我遇到了另一个问题:
  • memcpy 和 memmove 似乎没有按预期工作。在第一个循环中,短消息按预期处理(我收到的值与我在另一端发送的值相同),但随后 Protocol Buffer 解析的所有内容都失败了。我是不是误解了什么?

编辑:关于关于 ntohs 的评论——我目前正在将短片作为小端传输,忘记提及这一点。 (顺便说一句,我仍然会改变这个。)

第三次编辑:代码现在可以工作了,但我必须更改以下内容:

char* buffer[RCVBUFSIZE];
int recvsize= 0;
// Filling my buffer with as much as possible.
while(true) {
if(recvsize == RCVBUFSIZE) {
break;
} else if((recvsize+= recv(sock, buffer+recvsize, sizeof(buffer)-recvsize, 0)) < 1) {
break;
} else if(recvsize > 1) {
unsigned short msglength= 0;
memcpy((char *) &msglength, buffer+recvsize-sizeof(unsigned short), sizeof(unsigned short));
if(msglength == 0) { break; } // Received a full transmission.
}
}

所以首先我需要在 recvsize+= recv() 语句周围添加括号,其次因为非阻塞方法由于某种原因不起作用我现在正在检查最后两个字节是否当读取一个无符号短整数时,被传输为 0。如果我偶然读到一个不是长度字段的 0,这可能会导致问题。我可能会就此提出另一个问题。

我还将 protomsg 更改为 char[],但我不认为这真的改变了什么。 (我已经使用 void 数组进行解析了......)

最佳答案

如果您收到的消息总是在 10 个字节左右,并且 RCVBUFSIZE 大于此值,您将永远不会终止,直到出现读取数据错误。此外,代码中的 buffer 变量是一个 RCVBUFSIZE 指针数组,可能不是您想要的。

修改你的代码如下:

#define MINIMALMESSAGESIZE 10  // Or what the size may be
char buffer[RCVBUFSIZE];
int totalrecvsize= 0;
int recvsize= 0;
while(true) {
if(totalrecvsize >= MINIMALMESSAGESIZE) {
break;
} else if(recvsize= recv(sock, buffer+totalrecvsize, sizeof(buffer)-totalrecvsize, 0) < 1) {
break;
} else {
totalrecvsize += recvsize;
}
}

关于c++ - 在 C++ 中解析基于 TCP 的 TLV 协议(protocol)的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7954825/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com