简体   繁体   English

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

[英]TCP memcpy buffer returns rubbish data using C++

I'm doing something similar to Stack Overflow question Handling partial return from recv() TCP in C . 我正在做类似于堆栈溢出问题的操作,处理C中来自recv()TCP的部分返回

The data receive is bigger than the buffer initialised (for example, 1000 bytes). 接收到的数据大于初始化的缓冲区(例如1000字节)。 Therefore a temporary buffer of a bigger size (for example, 10000 bytes) is used. 因此,使用较大的临时缓冲区(例如10000字节)。 The problem is that the multiple data received is rubbish. 问题在于接收到的多个数据是垃圾。 I've already checked the offset to memcpy to the temporary buffer, but I keep receiving rubbish data. 我已经检查了memcpy到临时缓冲区的偏移量,但是我一直在接收垃圾数据。

This sample shows what I do: 此示例显示了我的工作:

First message received: 收到第一条消息:

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

Second msg onwards: 第二个味精起:

memcpy(tmpBuffer + offSet, dataRecv, 1000);

Is there something I should check? 我应该检查些什么吗?


I've checked the TCP hex that was sent out. 我检查了发出的TCP十六进制。 Apparently, the sender is sending an incomplete message. 显然,发件人发送的消息不完整。 How my program works is that when the sender sends the message, it will pack (message header + actual message). 我的程序的工作方式是,发件人发送消息时,它将打包(消息头+实际消息)。 the message header has some meta data, and one of it is the message length. 消息头具有一些元数据,其中之一是消息长度。

When the receiver receives the packet, it will get the message header using the message header offset and message header length. 当接收方接收到数据包时,它将使用消息头偏移量和消息头长度来获取消息头。 It will extract the message length, check if the current packet size is more than or equal to the message length and return the correct message size to the users. 它将提取消息长度,检查当前数据包大小是否大于或等于消息长度,并将正确的消息大小返回给用户。 If there's a remaining amount of message left in the packet, it will store it into a temporary buffer and wait to receive the next packet. 如果数据包中还有剩余的消息量,它将把它存储到一个临时缓冲区中,并等待接收下一个数据包。 When it receives the next packet, it will check the message header for the message length and do the same thing. 当它接收到下一个数据包时,它将检查消息头中的消息长度并执行相同的操作。

If the sender pack three messages in a packet, each message have its own message header indicating the message length. 如果发件人将三个消息打包在一个数据包中,则每个消息都有其自己的消息头,指示消息长度。 Assume all three messages are 300 bytes each in length. 假设所有三个消息的长度均为300字节。 Also assume that the second message sent is incomplete and turns out to be only 100 bytes. 还假定发送的第二条消息不完整,结果仅为100个字节。

When the receiver receives the three messages in a packet, it will return the first message correctly. 当接收方收到一个数据包中的三个消息时,它将正确返回第一条消息。 Since the second message is incomplete, my program wouldn't know, and so it will return 100 bytes from the second message and 200 bytes from the third message since the message header indicates the total size is 300 bytes. 由于第二条消息不完整,因此我的程序不知道,因此它将从第二条消息返回100个字节,从第三条消息返回200个字节,因为消息头表明总大小为300个字节。 Thus the second message returned will have some rubbish data. 因此,返回的第二条消息将具有一些垃圾数据。

As for the third message, my program will try to get the message length from the message header. 至于第三个消息,我的程序会尝试从邮件头信息的长度。 Since the first 200 bytes are already returned, the message header is invalid. 由于已经返回了前200个字节,因此消息头无效。 Thus, the message length returned to my program will be rubbish as well. 因此,返回给我的程序的消息长度也将是垃圾。 Is there a way to check for a complete message? 有没有一种方法来检查完整的消息?

Suppose you are expecting 7000 bytes over the tcp connection. 假设您希望通过tcp连接获得7000个字节。 In this case it is very likely that your messages will be split into tcp packets with an actual payload size of let's say 1400 bytes (so 5 messages). 在这种情况下,您的消息很有可能会被拆分为tcp数据包,实际有效负载大小为1400字节(所以是5条消息)。

In this case it is perfectly possible consecutive recv calls with a target buffer of 1000 bytes will behave as follows: 在这种情况下,目标缓冲区为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)
...

Now, in this case, when reading the 400 bytes packet you still copy the full 1000 bytes to your larger buffer, actually pasting 600 bytes of rubbish in between. 现在,在这种情况下,当读取400字节的数据包时,您仍将整个1000字节复制到较大的缓冲区中,实际上在它们之间粘贴了600字节的垃圾。 You should actually only memcpy the number of bytes received, which is the return value of recv itself. 实际上,您应该仅memcpy接收到的字节数,这是recv本身的返回值。 Of course you should also check if this value is 0 (socket closed) or less than zero (socket error). 当然,您还应该检查该值是0(关闭套接字)还是小于零(套接字错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM