C++ 通过recvfrom(UDP)接收数据包的一部分

C++ 通过recvfrom(UDP)接收数据包的一部分,c++,c,linux,sockets,udp,C++,C,Linux,Sockets,Udp,我试图通过recvfrom接收数据包的一部分。它实际上是这样工作的: recvfrom(sockfd, serialised_meta, 12, flags, src_addr, addrlen); recvfrom(sockfd, serialised_buf, BUFLEN, flags, src_addr, addrlen); bufd->Serialise(serialised_buf, BUFLEN+12); sendto(sockfd, serialised_buf, B

我试图通过recvfrom接收数据包的一部分。它实际上是这样工作的:

recvfrom(sockfd, serialised_meta, 12, flags, src_addr, addrlen);
recvfrom(sockfd, serialised_buf, BUFLEN, flags, src_addr, addrlen);
 bufd->Serialise(serialised_buf, BUFLEN+12);
 sendto(sockfd, serialised_buf, BUFLEN+12, flags, dest_addr, addrlen);
数据的发送方式如下:

recvfrom(sockfd, serialised_meta, 12, flags, src_addr, addrlen);
recvfrom(sockfd, serialised_buf, BUFLEN, flags, src_addr, addrlen);
 bufd->Serialise(serialised_buf, BUFLEN+12);
 sendto(sockfd, serialised_buf, BUFLEN+12, flags, dest_addr, addrlen);
因此,我们的想法是先读取一些元数据,然后决定是否接收其他数据。问题是我在第二个缓冲区(序列化)的开头收到4'/0'字节。这似乎不是序列化问题,我以前使用过我的序列化,当我同时接收整个数据包(元数据和数据)时,一切都很酷。 有没有办法解决这个问题


另外,我知道我可以跳过不必要的字节),但无论如何,为什么会发生这种情况?

UDP不是“流”协议。。。一旦您执行了初始recvfrom,数据包的其余部分将被丢弃。第二个recvfrom正在等待下一个数据包…

UDP对消息进行操作,而不像TCP那样对流进行操作。使用UDP时,
sendto()
recvfrom()
之间存在一对一的关系。没有在UDP中接收部分数据的选项,这是一种全有或全无的传输类型。您必须一次完成整个
BUFLEN+12
消息,然后决定是否实际使用它。这就是UDP的工作方式。

好的,那么我的解决方案怎么能工作呢?那只是出于好奇)。如果数据包的剩余部分被丢弃,第二个recvfrom应该可以工作。提前谢谢!现在,我想,首先获取meta的最好方法是使用peek标志?如果你谈论的是数据包长度,你可以通过使用
ioctl
FIONREAD
来确定。您可以使用
MSG_PEEK
,但我不会打扰您,除非您的数据包很大,而您的元数据很小。。。可能最好跳过
ioctl
并全部查看,并准备好一个最大缓冲区大小(适用于您的应用程序),然后跳过/丢弃数据。这真的是一次完成还是一无所有?我记得在某个地方读到过这样一句话:应该总是检查
recvfrom()
的返回值,将其与预期大小进行比较,然后重复调用
recvfrom
,直到收到所有数据。不幸的是,我不记得在哪里读到的。如果这是没有意义的,它会让我的生活更轻松;)。。。我所描述的内容是否可能只适用于TCP,而不适用于UDP?我找到了一个网站,在那里他们描述了TCP(不是我提到的那个,但或多或少是相同的技术:)@tobi303这是TCP中发生的事情,而不是UDP中发生的事情。尽管返回值实际上是读取的字节数,但如果提供的缓冲区太小,无法接收整个消息,UDP中的
recvfrom
会尽可能多地填充缓冲区,丢弃剩余的未读数据,并报告
EMSGSIZE
错误。所以你只有一次机会收到完整的信息。谢谢你的回复。所以,草率地说,是全部还是错误。如果出现错误,我没有机会恢复完整的消息。听起来很简单:)