【发布时间】:2011-11-01 00:57:21
【问题描述】:
我正在尝试通过 TCP 实现 (T)LV 协议,从 python 客户端发送协议缓冲区并使用 C++ 服务器接收。
我的代码或多或少是这样的:
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 函数来检查是否有要读的东西。我会尝试一下。 但是当我只调用一次来跳过这个问题时(收到的消息大约 10 个字节,所以我希望在一次调用中收集所有内容。)我遇到了另一个问题:
- memcpy 和 memmove 似乎没有按预期工作。在第一个循环中,short 被按预期处理(我收到了与我在另一端发送的相同的值),但随后解析协议缓冲区的所有内容都失败了。我是不是误会了什么?
编辑:关于 ntohs 的评论——我目前正在以 little-endian 的形式传输短片,忘记提及了。 (顺便说一句,我仍然会改变它。)
第三次编辑:代码现在可以工作了,但我必须更改以下内容:
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 数组..)
【问题讨论】:
-
您应该在收到的
short上调用ntohs(并在发送时调用htons-“网络到主机,短”/“主机到网络,短”)