How to use asynchronous Receive for UdpClient in a loop?

て烟熏妆下的殇ゞ 提交于 2019-12-01 13:27:59

For newer methods using TAP instead of Begin/End method you can use the following in .Net 4.5

Quite simple!

Asynchronous Method

    private static void UDPListener()
    {
        Task.Run(async () =>
        {
            using (var udpClient = new UdpClient(11000))
            {
                string loggingEvent = "";
                while (true)
                {
                    //IPEndPoint object will allow us to read datagrams sent from any source.
                    var receivedResults = await udpClient.ReceiveAsync();
                    loggingEvent += Encoding.ASCII.GetString(receivedResults.Buffer);
                }
            }
        });
    }

Synchronous Method

As appose to the asynchronous method above, this can be also implemented in synchronous method in a very similar fashion:

    private static void UDPListener()
    {
        Task.Run(() =>
        {
            using (var udpClient = new UdpClient(11000))
            {
                string loggingEvent = "";
                while (true)
                {
                    //IPEndPoint object will allow us to read datagrams sent from any source.
                    var remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    var receivedResults = udpClient.Receive(ref remoteEndPoint);
                    loggingEvent += Encoding.ASCII.GetString(receivedResults);
                }
            }
        });
    }

I've added some code to demonstrate how you could implement the loop by using BeginReceive/EndReceive. This shows you a stripped down version you could easily modify or implement:

UdpClient local;
bool stop;

public void StartReceiving() 
{
    local = new UdpClient(serverIP);
    Receive(); // initial start of our "loop"
}

public void StopReceiving() 
{
    stop = true;
    local.Client.Close();
}

private void Receive() 
{   
    local.BeginReceive(new AsyncCallback(MyReceiveCallback), null);
}

private void MyReceiveCallback(IAsyncResult result) 
{
    IPEndPoint ip = new IPEndPoint(IPAddress.Any, 0);
    local.EndReceive(result, ref ip);

    if (!stop)
    {
        Receive(); // <-- this will be our loop
    }
}

Have fun

Another approach with some support for cancelling. I prefer the recursive feel to the while(true) loop.

private async void Listen()
{
    var resp = await _udpClient.ReceiveAsync().ConfigureAwait(false);

    var eventHandler = PacketReceived;
    if (eventHandler != null)
        eventHandler(this, new UdpPacketReceivedEventArgs(resp));

    if (_running)
        Listen();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!