TCP memcpy缓冲区使用C ++返回垃圾数据

时间:2011-08-22 05:18:47

标签: c++ sockets

我正在做类似Stack Overflow问题 Handling partial return from recv() TCP in C 的事情。

数据接收大于初始化的缓冲区(例如,1000字节)。因此,使用更大尺寸的临时缓冲区(例如,10000字节)。问题是收到的多个数据是垃圾。我已经将memcpy的偏移量检查到临时缓冲区,但我一直收到垃圾数据。

此示例显示了我的操作:

收到第一条消息:

memcpy(tmpBuff, dataRecv, 1000);
offSet = offSet + 1000;

第二个消息:

memcpy(tmpBuffer + offSet, dataRecv, 1000);

我应该检查一下吗?


我已经检查了发送的TCP十六进制。显然,发件人发送的邮件不完整。我的程序如何工作是当发件人发送邮件时,它将打包(邮件标题+实际邮件)。消息头有一些元数据,其中一个是消息长度。

当接收方收到数据包时,它将使用消息头偏移量和消息头长度获取消息头。它将提取消息长度,检查当前数据包大小是否大于或等于消息长度,并将正确的消息大小返回给用户。如果数据包中剩余剩余数量的消息,它将把它存储到临时缓冲区并等待接收下一个数据包。当它收到下一个数据包时,它将检查消息头的消息长度,并做同样的事情。

如果发件人在数据包中打包三条消息,则每条消息都有自己的消息标题,指示消息长度。假设所有三条消息的长度均为300字节。还假设发送的第二条消息不完整,结果只有100字节。

当接收方收到数据包中的三条消息时,它将正确返回第一条消息。由于第二个消息不完整,我的程序将不知道,因此它将从第二个消息返回100个字节,从第三个消息返回200个字节,因为消息头指示总大小为300个字节。因此,返回的第二条消息将有一些垃圾数据。

至于第三条消息,我的程序将尝试从消息头中获取消息长度。由于已返回前200个字节,因此消息头无效。因此,返回到我的程序的消息长度也将是垃圾。有没有办法检查完整的消息?

1 个答案:

答案 0 :(得分:5)

假设您希望通过tcp连接获得7000个字节。在这种情况下,很可能您的消息将被拆分为tcp数据包,实际有效负载大小为1400字节(因此为5条消息)。

在这种情况下,完全有可能使用1000字节的目标缓冲区进行连续recv调用,其行为如下:

recv -> reads 1000 bytes (packet 1)
recv -> reads 400 bytes (packet 1)
recv -> reads 1000 bytes (packet 2)
recv -> reads 400 bytes (packet 2)
...

现在,在这种情况下,当读取400字节数据包时,您仍然将完整的1000个字节复制到较大的缓冲区,实际上在它们之间粘贴了600字节的垃圾。实际上你应该只记忆收到的字节数,这是recv本身的返回值。当然,您还应检查此值是0(套接字关闭)还是小于零(套接字错误)。