0

我有一个 udp 客户端和一个 udp 服务器。udp 客户端和服务器实际上是在物理上断开连接的。所以我只能向 udp 服务器发送消息,但我无法确认数据是否正确接收。

所以我正在做的是发送一个 4 字节的标头,它将指定我将要发送的数据量。然后我根据我之前发送的大小读取数据。

客户端

// Sending Header(header is the size of the data)
byte[] header = BitConverter.GetBytes(data.Count());
socket.SendTo(header, 0, header.Count(), SocketFlags.None, outEP);
// Sending Data
socket.SendTo(data, 0, data.Count(), SocketFlags.None, outEP);

服务器端

// Receiving input size
int receivedCount = socket.EndReceive(result);
// Header is filled on BeginReceive
Int32 count = BitConverter.ToInt32(header, 0);
if(count != receivedCount) throw;
// Then I receive the count relevent
socket.Receive(data, 0, count, SocketFlags.None);

出现了几个问题:

  1. 计数!=收到计数

    这就是我进行检查的原因,但有时会发生,有时不会。我确实需要最大程度的保证。我发现当计数不同时,不是因为字节数下降或网络问题。我只是有时没有收到标题 - 只有数据,当我读取 4 个字节时,我实际上读取了 4 个字节的数据,这就是它失败的原因。

    数据有时会覆盖标题。 这是为什么?我该如何解决这个问题?

  2. 有时我也会在 socket.Receive 上收到以下错误

    在数据报套接字上发送的消息大于内部消息缓冲区或某些其他网络限制,或者用于接收数据报的缓冲区小于数据报本身

    问题是有时会发生这种情况,而大多数情况下不会……我可以在最大缓冲区中接收所有内容……但是我会遇到内存问题。

    这应该是高性能和尽可能有保证的交付。这必须是udp,因为服务器端无法物理联系客户端它是一种方式 - 客户端到服务器。

4

2 回答 2

1

使用 UDP 时,您将需要双向通信,并确保没有丢失、重复或混乱的数据包。
你看过像PGM - Pragmatic Multicast 这样的协议吗?
此外,您可能需要一个线程来快速清理网络堆栈,然后将数据发布到队列或其他一些内存数据结构中。网络堆栈比您想象的要小得多,而且比您想象的更快。
编辑:UDP的问题在于,根据定义,您可能丢失或重复包或订单更改,即使接收器检测到它们,当无法通信时接收器应如何请求更正它们。

于 2012-06-25T12:49:55.933 回答
1

UDP 不保证数据包按照您发送它们的顺序到达(或者它们完全到达)。我怀疑任何东西都会被覆盖/覆盖。您必须在一个数据包中发送标头和有效负载。

你考虑过使用 TCP 吗?您可能会争辩说 UDP 更快,但如果您要自己实现数据包重新排序,您将失去这种优势。(错过了它必须是UDP)。

如果您查看 TCP(网络层处理重传)或UDP 上的SIP(​​软件处理重传),有办法检测丢失的数据包并重新传输它们。例如,您可以为您的数据包编号,并让接收者确认收到每个数据包。

于 2012-06-25T11:53:12.390 回答