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 接收事件的主要内容,如果未能解决你的问题,请参考以下文章
从使用 UdpClient 接收的 UDP 包中获取客户端 IP