C#.Net UdpClient 接收事件

Posted

技术标签:

【中文标题】C#.Net UdpClient 接收事件【英文标题】:C#.Net UdpClient Receive Event 【发布时间】:2014-06-15 02:28:26 【问题描述】:

我想知道当我的 UdpClient 接收到数据时,是否有任何方法可以触发事件? (System.Net.Sockets.UdpClient)

我尝试覆盖它的 UdpClient.Receive 但我不能根据 this 因为可覆盖的成员必须标记为虚拟或抽象。

我目前的做法是在特定时间间隔在 Threading.Timer 上运行 TimerCallback 以获取我的数据,但我更愿意在传入数据到达时接收它,而不是重复获取它。

关于如何执行此操作或我必须在间隔手动接收的任何建议、建议或指示?

【问题讨论】:

我相信 UdpClient.Receive 方法会阻塞当前线程,直到它接收到数据? 这和 ASP.NET 有什么关系? Receive messages continuously using udpClient的可能重复 【参考方案1】:

重写Receive 方法对您没有任何帮助 - 它不是在 UDP 客户端接收数据时调用的方法,而是当您想要等待传入数据时调用的方法

但是,Receive 方法会阻塞。这意味着您实际上不必定期检查 - 您可以简单地检查(几乎)无限循环。只需在不同的线程中执行即可。

void Loop(CancellationToken token)

  var remoteEP = default(IPEndPoint);

  while (!token.IsCancellationRequested)
  
    var data = client.Receive(ref remoteEP);

    yourForm.Invoke(DataReceived, data);
  

当然,由于这是简单的 I/O,因此无需占用线程来执行此操作 - 您可以使用异步 I/O:

public Task Loop(CancellationToken token)

  using (UdpClient client = new UdpClient(80))
  
    while (!token.IsCancellationRequested)
    
      var data = await client.ReceiveAsync();

      // Process the data as needed
    
  

在 winforms 或 WPF 应用程序中,这几乎可以自动运行 - 您只需在 btnStart_Click 事件处理程序中使用此代码,它会在后台等待数据时保持您的 UI 响应;并且每当数据返回时,它将在 UI 线程上执行其余代码 (Process the data as needed) - 无需手动创建任何线程或处理调度。

当然,处理终止有点棘手,但使用 UDP 总是很棘手 - 基本上,您要么必须使用支持取消的更手动的方式(ReceiveAsync 只是 BeginReceive 和 @ 的包装器987654329@ 不支持取消),或者您将使用设置取消令牌然后向自己发送一个长度为 0 的数据包的旧技巧(导致 Receive 调用结束并返回一个长度为零的字节数组)。

【讨论】:

使用 .Receive 时必须使用 UDPClient 指定端点 @VoteCoffee 对,我的错。我修好了:)【参考方案2】:

您也可以使用 Rx 扩展来接收数据。

UpdClient 中的ReceiveAsync 包装在Observable.FromAsync 中并订阅可观察对象。

UdpClient client = new UdpClient(..., ...);
var obs = Observable.FromAsync(client.ReceiveAsync);
var sub = obs.Subscribe(...);

【讨论】:

【参考方案3】:

UdpClient.Receive 会阻止执行,直到它从端点接收到数据。但是有一个异步替代方案,UdpClient.BeginReceive。它不完全是一个事件,但以类似的方式工作,您可以封装它并触发您自己的事件。文档(带有代码示例)可以在这里找到:http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v=vs.110).aspx

【讨论】:

以上是关于C#.Net UdpClient 接收事件的主要内容,如果未能解决你的问题,请参考以下文章

C# UdpClient使用

从使用 UdpClient 接收的 UDP 包中获取客户端 IP

UDP 协议 C# UdpClient乱序接收数据包丢失的问题 Socket ReceiveBufferSize

UDP Client 和 Socket 的区别

UDP C++接收

使用udpclient在一个端口并发发送和接收数据