Receiving and processing continous packets using UDP

.net, asynccallback, c#, sockets, udp

Solution

Looks like you are creating some sort of recursive handler there. I am unsure how that will work, probably not in a good way. I usually go for a separate reader thread that listens to incoming data and passes it on to an event. This has served me well in the past. I have not looked into using async for this though.

Here is some example code on how to use a separate thread to handle incoming UDP data. It is not complete but should give you an idea of how to set it up.

    private Thread _udpReadThread;
    private volatile bool _terminateThread;

    public event DataEventHandler OnDataReceived;
    public delegate void DataEventHandler(object sender, DataEventArgs e);

    private void CreateUdpReadThread()
    {
        _udpReadThread = new Thread(UdpReadThread) { Name = "UDP Read thread" };
        _udpReadThread.Start(new IPEndPoint(IPAddress.Any, 1234));
    }

    private void UdpReadThread(object endPoint)
    {
        var myEndPoint = (EndPoint)endPoint;
        var udpListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        // Important to specify a timeout value, otherwise the socket ReceiveFrom() 
        // will block indefinitely if no packets are received and the thread will never terminate
        udpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100);
        udpListener.Bind(myEndPoint);

        try
        {
            while (!_terminateThread)
            {
                try
                {
                    var buffer = new byte[1024];
                    var size = udpListener.ReceiveFrom(buffer, ref myEndPoint);
                    Array.Resize(ref buffer, size);

                    // Let any consumer(s) handle the data via an event
                    FireOnDataReceived(((IPEndPoint)(myEndPoint)).Address, buffer);
                }
                catch (SocketException socketException)
                {
                    // Handle socket errors
                }
            }
        }
        finally
        {
            // Close Socket
            udpListener.Shutdown(SocketShutdown.Both);
            udpListener.Close();
        }
    }

    public class DataEventArgs : EventArgs
    {
        public byte[] Data { get; private set; }
        public IPAddress IpAddress { get; private set; }

        public DataEventArgs(IPAddress ipaddress, byte[] data)
        {
            IpAddress = ipaddress;
            Data = data;
        }
    }

Problem

This is my current setup (using UDP): ``` void OnDataReceived(IAsyncResult result) { IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0); byte[] buffer = socket.EndReceive(result, ref ep); Packet p = new Packet(Encoding.ASCII.GetString(buffer, 0, buffer.Length)); //process packet socket.BeginReceive(new AsyncCallback(OnDataReceived), socket); } ``` I was wondering what would happen if I immediately call socket.BeginReceive after calling EndReceive and then process the packet to obtain a continous packet flow like this: ``` void OnDataReceived(IAsyncResult result) { IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0); byte[] buffer = socket.EndReceive(result, ref ep); socket.BeginReceive(new AsyncCallback(OnDataReceived), socket); Packet p = new Packet(Encoding.ASCII.GetString(buffer, 0, buffer.Length)); //process packets } ``` If a packet is received as soon as I call BeginReceive, would this conflict with the current packet processing somehow? Also if this would not conflict would changing to TCP make this disfunctional?

Original source

Related problems