如何确定 Windows 中 UDP 有效负载的大小?

问题描述

我正在尝试找出如何解决 Windows 中的问题。我使用的是 C# (net5.0),但如果您知道 C 或 C++ 中的答案,那应该不是真正的问题,因为我可以毫无问题地调用 DLL 中的函数

在 Windows 10 上使用多播测试 UDP 处理时,我发现了一个问题:当我的缓冲区对于传入的有效负载来说太短时,System.Net.sockets.socket.ReceiveMessageFrom 将缓冲区填充到其最大容量,不会设置 {{ 1}} 或 Socketoptions.Fragmented 标志(并且在调用之前设置会导致“不支持”异常),并且 Socketoptions.Multicast 字段为空。 IPPacketinformation.Address 的返回值是我的缓冲区的大小,而不是数据包的大小。无论我做什么,我似乎都无法获得必要的分配大小(即使使用 ReceiveMessageFrom)。

当我的缓冲区足够长以接收有效载荷时,Socketoptions.Peek 会填充缓冲区,设置 (System.Net.sockets.socket)s.ReceiveMessageFrom,并将 Socketoptions.Multicast 字段设置为它从中接收的多播组 IP。这种情况下的返回值是实际接收到的数据量,当我的缓冲区大于接收到的数据时。

在 Linux 上,我可以设置 IPPacketinformation.Address 并且它会正常工作:填充了太小的缓冲区,但 Socketoptions.Fragmented 的返回值设置为传入数据的实际大小。结合ReceiveMessageFrom,这允许我分配一个足够大的新缓冲区来容纳它,并检索完整数据。 (这非常类似于使用长度为 0 的缓冲区调用 Windows 注册函数,并被告知您实际需要多大的缓冲区。)

Linux 方法的替代方法是尝试分配接口允许的大小的缓冲区,但 Socketoptions.Peek 没有 System.Net.networkinformation.IPInterfaceProperties 成员,而 .Mtu 有。我不知道如何获得帧的最大大小,这是必要的,因为某些驱动程序支持一种称为“巨型帧”的功能,可以超过 64kb。)

简而言之:我的多播发送器程序发送 26 个字节长的数据包,其中包含从 A 到 Z 的整个大写美国字母表。

我的multicastreceiver程序是我进行更改的地方。当我将该程序中的接收缓冲区设置为小于 26 字节长时,我得到了有问题的行为。当我将它设置为 26 字节或更长时,我得到了正确的行为。

这个问题不是关于操作系统级或 Winsock 级缓冲区。如果需要,我将分别调整它们。我特别想确保我用 System.Net.networkinformation.IPv6InterfaceProperties 检索的数据不会被截断。 (当操作系统级别没有足够的缓冲区空间用于排队的数据时,它只会丢弃整个数据包。它不会将部分数据包写入队列。我的应用程序正在从对 {{1 }},这并不表示有任何内容被截断。我需要弄清楚如何解决这个问题。)

我不能通过编码为数据本身保留的区域中的数据大小来丢失数据包空间,因为这至少需要 2 个字节,而且我已经需要在这里压缩很多。 UDP 标头已经有一个 Length 字段,该字段包含我需要的内容,但我无法访问它。

感谢您的帮助!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...