2012-06-25 263 views
0

我有一个udp客户端和一个udp服务器。 udp客户端和服务器实际上是断开连接的。 所以我只能发送消息到udp服务器,但我无法确认数据是否被正确接收。c#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. 数= receivedCount

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

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

  2. 有时我还获得对socket.Receive

    数据报套接字上发送的消息大于内部消息缓冲器或某种其它网络的限制,或者用于接收缓冲器较大以下错误数据报成小于数据报本身

    问题是,有时会发生,大部分时间它不... 我可以只接收它在一个最大的缓冲区..但然后我会有内存问题。

    这应该是在高性能和保证交付尽可能.. 这必须是udp,因为服务器端不能实际接触客户端 它是一种方式 - 客户端到服务器。

+0

UDP设计不提供确认对方收到数据包。如果您想要确认交付,则使用错误的协议。 UDP是无状态的。 –

回答

1

UDP并不保证数据包以您发送它们的顺序到达(或者它们到达所有地方)。我怀疑任何被覆盖/覆盖的东西。您将不得不在一个数据包中发送标题和有效负载。

您是否考虑过使用TCP?你可能会争辩说UDP的速度更快,但是如果你打算自己实现数据包重组,那么你将失去这种好处。 (错过了它必须是是UDP)。

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

1

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

+0

我不需要双向沟通。我需要一些交付保证的单向沟通。 你能解释一下你想用单线程来清理网络吗? – Lee

+1

我通常有一个128 kb的字节数组和接收和处理线程。如果128 kb已满,那么我知道我太慢了,并断开了自己。 – weismat

+0

那么我的问题是如何缩小丢包的可能性 - 程序化 - 也许我可以在每个发送请求后执行Thread.Sleep()?也许发送一个数据包,然后只是有一个大的缓冲区?什么是最佳实践?编辑 - 我看到你的回复。是的,这是一个选项.. – Lee