繁体   English   中英

如何在C中读取可变长度的UDP数据包

[英]How to read UDP packet with variable length in C

我正在通过UDP发送一个C结构

struct packet{
    int numInt;
    int* intList; //malloc'ed as (sizeof(int)*numInt)
}

它将被序列化为[numInt][intList[0]]...[intList[numInt-1]]

我的理解是,在UDP上调用recvfrom将读取整个数据包,即使缓冲区不包含那么多字节。 使用一个非常大的缓冲区是我唯一的选择吗?

您可以将MSG_PEEK传递给recvfrom以确切了解缓冲区需要的大小。 所以只要recvfrom有几个字节MSG_PEEK找到numInt然后recvfrom真实的东西(这次没有MSG_PEEK )。

该标准说明了MSG_PEEK ,但kernel.org更好地说明了这一点:

MSG_PEEK

此标志使接收操作从接收队列的开头返回数据,而不从队列中删除该数据。 因此,后续的接收呼叫将返回相同的数据。

显然,在某些时候你会开始想知道将系统调用数量加倍以节省内存是否值得。 我认为不是。

UDP数据包作为一个整体发送和接收。 如果你收到它,大小是正确的。 你唯一要做的就是在read()或recv()或recfrom()上提供足够大的缓冲区。 有效负载内的长度字段是多余的,因为read()将告诉您正确的大小。 它也很危险,因为它依赖于具有相同字节顺序的发送方和接收方。

您可以尝试使用一个小的缓冲区,只要设置了MSG_PEEK标志就足够大,以获得numInt 然后你可以找到你真正需要的大小,并在没有MSG_PEEK情况下再次接收以获得整个事情。

我很确定recvfrom会读取第三个参数len告诉它的字节数。 如果有更少的可用字节,它将返回那里的内容。 如果还有更多,它将返回len个字节。 您可能需要进行其他调用才能获得所需的所有数据。

暂无
暂无

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

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