c#UDP客户端服务器问题

时间:2012-06-25 09:01:36

标签: c# connection udp client-server

我有一个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. count!= receivedCount

    这就是我做检查的原因,但它有时会发生,有时它不会......我确实需要最大限度的保证。 我发现当计数不同时,不是因为字节数减少或网络问题。我有时候不接收标题 - 只有数据,当我读取4个字节时,我实际上读取了4个字节的数据,这就是它失败的原因。

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

  2. 有时我也会在socket.Receive上出现以下错误

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

    问题在于有时会发生,而且大部分时间都没有...... 我可以在最大缓冲区中收到它。但是我会遇到内存问题。

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

2 个答案:

答案 0 :(得分:1)

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

您是否考虑过使用TCP?您可能会认为UDP速度更快,但如果您要自己实施数据包重新处理,则会失去该优势。(错过必须是UDP)。

如果你看TCP(网络层处理重传)或SIP通过UDP(软件处理重传),有办法检测丢失的数据包并重新发送它们。例如,您可以对数据包进行编号,并让接收方确认接收每个数据包。

答案 1 :(得分:1)

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