UDP 套接字:如何确定可用字节何时是完整数据报

UDP Socket: How to determine when the available bytes are a full datagram

我有一个 .NET 套接字 (System.Net.Sockets.Socket),我想将其用于 UDP(无连接通信)。我想通过轮询接收数据报,也就是我想调用Available方法来检查是否有数据报可用。如果是,我调用 Receive 以无阻塞地接收它。如果不是,我会等待并稍后再次轮询。但现在我的问题如下:

Available 只有 returns 有多少字节可供读取而不阻塞。它不会说明这些字节是否足以构成一个完整的数据报。我不知道我收到的数据报有多大,所以我不能将此检查硬编码到某个数字。

如何确定一个数据报何时结束以及下一个数据报何时开始?

正如 Philip 所说,使用 UDP 您要么获得整个数据报,要么根本得不到。如果套接字报告数据可用,它应该是整个数据报的数量(或数据报的某种组合)。

就是说,在您的 post 中您说您想使用轮询来接收数据。对于任何实现来说,这都是一个糟糕的选择。 .NET 的网络 I/O 具有非常好的异步实现模型,您可以使用(包括将套接字包装在 NetworkStream 对象中并使用 ReadAsync()async/await C# 5 的特性),这将是一个更好的选择。

此外,您应该非常确定 UDP 实际上就是您要使用的协议。由于它的不可靠性,它不适用于几乎所有 运行-of-the-mill 网络应用程序。不能保证:

  • 您发送的任何数据都会收到。网络允许丢弃数据报。
  • 接收到的数据将按照发送时的相同顺序接收。数据报的传递可能会被网络重新排序。
  • 收到的数据将是唯一的。允许网络多次传送相同的数据报。

对于大多数网络应用程序,需要保护业务层免受此类故障的影响,这意味着在业务层和网络层之间添加您自己的可靠性层。 IE。重塑 TCP。

在 TCP 上强加消息传递范例比在 UDP 上强加可靠范例容易得多,因此在大多数情况下更适合使用所有网络的 TCP I/O 而不是 UDP。