0

我需要实现一个 UDP 服务器来接收来自一系列设备的报告,这些设备只能使用此协议进行报告(我无法更改它们)。从历史上看,我使用 C++ 和 Winsock 来实现这种服务器(将套接字绑定到侦听端口并使用 recvfrom)。这种实现确保即使我的程序实际上没有阻塞 recvfrom(),也会在 Winsock 库中缓冲少量数据包等待它,因此丢失的数据包更少。如果底层网络驱动程序支持,我什至可以尝试使用 WSAIoctl() 调整缓冲区大小。

我正在尝试为此目的实现 .Net (Framework 4) 服务,但我在 Internet 上找到的所有示例都使用 UdpClient 类,这在某种程度上很好,但似乎不太适合这项任务,因为它允许在听力过程中出现“漏洞”。例如:

Dim server = New UdpClient(...)
Dim remote = New IPEndPoint(IPAddress.Any, 0)
...
Dim pkt1 = server.Receive()
... some processing A ...
Dim pkt2 = server.Receive(remote)
... some processing B ...
Dim pkt3 = server.Receive(remote)

API在UDPClient类中实现的方式,在我看来,如果数据包在程序的“处理A”或“处理B”阶段到达,可能会丢失,因为实际上没有套接字绑定到监听地址/那个时候的端口,操作系统应该丢弃它们。我可以尝试尽可能快地进行“处理 A”和“处理 B”,但它们会一直存在。

我完全意识到 UDP 是一种无连接/不可靠的协议,这意味着无论我做什么,数据包都可能会丢失,但是在数据包到达服务器丢失数据包只是因为 API 有限制对我来说感觉很愚蠢。

为了确保没有数据包丢失(只要它已经到达服务器),需要一个永久绑定到侦听端口的对象。我可以在 VB6 中使用 Winsock ActiveX 控件做到这一点,就像我可以使用 C/C++ 中的二进制 Winsock API 一样,但我无法在 .Net 中找到这样做的方法。有办法吗?我的分析是正确的还是我遗漏了一些观点?

提前致谢,

吉尔。

4

1 回答 1

1

除非您通过发送如此大量的数据来填充网络缓冲区,或者您需要很长时间才能再次调用接收,否则不会丢失任何数据包。如果您在执行其他操作时收到数据包,它们将被缓冲在网络缓冲区中(这就是它的用途),直到您再次调用接收,这将在 UDP 中一次传送一个数据包(数据报)。

(我很惊讶直接使用 Winsock 不一样!)

通常,使用同步 Receive() 方法的对等点将具有如下循环:

// Disclaimer: I don't know VB! 

While True
   Dim datagram = server.Receive()
   // do stuff
于 2013-10-24T00:45:59.817 回答