Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C套接字中调用recv两次时丢失接收的数据_C_Sockets_Embedded Linux - Fatal编程技术网

在C套接字中调用recv两次时丢失接收的数据

在C套接字中调用recv两次时丢失接收的数据,c,sockets,embedded-linux,C,Sockets,Embedded Linux,我试图读取从网络接收到的前4个字节以获得整个消息长度,然后我得到所有消息,如下所示: #include <sys/socket.h> int len,length; char *buffer, lengthX[4]; recv(com_handle, lengthX, 4, 0); sscanf(lengthX, "%" S(4) "X", &len); length=recv(com_handle, buffer , len, 0); #包括 长度; 字符*缓冲区,长度为

我试图读取从网络接收到的前4个字节以获得整个消息长度,然后我得到所有消息,如下所示:

#include <sys/socket.h>
int len,length;
char *buffer, lengthX[4];
recv(com_handle, lengthX, 4, 0);
sscanf(lengthX, "%" S(4) "X", &len);
length=recv(com_handle, buffer , len, 0);
#包括
长度;
字符*缓冲区,长度为[4];
recv(com_手柄,长度为4,0);
sscanf(长度X,%“S(4)”X和长度);
长度=recv(com_句柄,缓冲区,长度,0);
由于某些原因,我丢失了消息其余部分的13个字节。 有什么想法吗?

函数不能保证读取指定的完整字节数。其Linux手册页对此进行了如下描述:

receive calls通常返回所有可用数据,最多返回请求的金额,而不是等待收到请求的全部金额

在这种情况下,它就像阅读(2),在大多数情况下我更喜欢阅读。套接字的类型(流与数据报)会影响这一点,但对于这两种函数,您可能需要准备循环,反复读取以收集所有消息片段


并始终检查系统调用的返回值。在这种情况下,您不仅需要这样做来检测错误,还需要这样做来确保正确读取。

您需要连续检查recv的返回值,以了解每次recv调用接收到的字节数。原因是您使用的是流协议,您可以随时接收任意数量的字节,而不是以您在发送方发送字节的方式。

如果您发送100个字节,然后紧接着再次发送100个字节,很可能会收到200个字节,但也可能是150和50或其他。您的逻辑应该这样编写:数据流可能被分割成任意大小的多个片段。因此,您需要一个始终调用receive并填充一些中间缓冲区的某种循环。只有当你收到4个字节时,你才能知道还有多少字节,但你不知道需要多少recv呼叫。此外,如果您发送多条此类消息。长度后跟数据的长度字节,然后是长度后跟数据(2条消息)。请注意,您将以连续流的形式接收此消息,因此您可能会接收上一个数据包的数据、下一个数据包的长度以及下一个消息的某些字节。您需要相当多的逻辑来处理这个问题,因为您的4字节长度本身可能会被打断,并分布在2个或更多的recv调用中。

还要检查是否接收到0字节,因为这意味着对等方已关闭其连接端


你应该多读一点关于网络编程的知识,我总是在这里看到同样的错误,人们只是不明白流媒体协议是什么。但是这种信息可以在互联网上找到。首先开始阅读,然后是理解,然后是实验和编码,然后是进一步理解。

您的代码是错误的和不完整的。什么是
msgLength
?你是对的,我修改了它的“长度”,因为我从大的源代码复制了它。你是否尝试打印从网络收到的len的实际值?我无法猜测
%d“S(4)”X“
是否正确…现在有两个名为“length”的变量。您必须正确处理recv()返回的值。忽视它是非常非常糟糕的(