C#.Net UdpClient接收事件

时间:2014-04-29 08:45:55

标签: c# .net udpclient

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

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

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

有关我如何执行此操作的任何建议,建议或指示,或者我是否必须按时间间隔手动接收?

提前致谢。

3 个答案:

答案 0 :(得分:4)

覆盖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总是很棘手 - 基本上,你要么必须使用支持取消的更手动的方式({{1 }}只是ReceiveAsyncBeginReceive不支持取消的包装器,或者您使用设置取消令牌然后发送0长度的旧技巧数据包给自己(导致EndReceive调用结束并返回零长度字节数组。)

答案 1 :(得分:3)

您也可以使用Rx Extensions接收数据。

ReceiveAsync中的UpdClient换成Observable.FromAsync并订阅可观察对象。

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

答案 2 :(得分:2)

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