1

My udp class is not receiving the updated value from the stream. Device sends data continuously and when any alarm activated it add the code in stream and sends the updated value but my class is not receiving the updated value unless I restart the program.

here is my UDPListener class.

public class 
{
    public static int PORT_NUMBER { get; set; }
    public string IpAddress { get; set; }
    private readonly UdpClient udp;
    public event Action<object, EventArgs> msgChanged;
    IAsyncResult ar_ = null;

    public UDPListener(string ipaddr, int port)
    {
        IpAddress = ipaddr;
        PORT_NUMBER = port;
        udp = new UdpClient(PORT_NUMBER);
        Start();
    }

    public void Start()
    {
        StartListening();
    }

    public void Stop()
    {
        try
        {
            udp.Close();
        }
        catch { /* not necessary */ }
    }

    private void StartListening()
    {
        ar_ = udp.BeginReceive(Receive, new object());
    }

    private void Receive(IAsyncResult ar)
    {
        try
        {
            Thread.Sleep(150);
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse(IpAddress), PORT_NUMBER);
            byte[] bytes = udp.EndReceive(ar, ref ip);
            string message = Encoding.ASCII.GetString(bytes);

            //raise event..
            if (message.StartsWith("S"))
                if (msgChanged != null)
                    msgChanged(message, EventArgs.Empty);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error in UDPListner..." + ex.Message);
        }
        finally
        {
            StartListening();
        }
    }
}

Now what is happening when the program starts it will receive data "S0000.." but when alarm raises data changes to "S8000..etc" but this class continuously receiving the same "S000.." data unless I restart the class.

When I run the udp listener in while loop its works perfectly fine, it receives the updated stream and changes when alarm goes off.

here is the code for while loop udp.

while (!StopRunning)
{
    Thread.Sleep(150);
    udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);
    var ep = default(IPEndPoint);
    var data = udp.Receive(ref ep);
    udp.Close();
    string msg = Encoding.ASCII.GetString(data);
    if (msgChanged != null)
        msgChanged(msg, EventArgs.Empty);
}

But I cannot make use of while loop because I have to fit this program in window service.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
dawncode
  • 578
  • 1
  • 8
  • 22
  • Two questions. First, what's the purpose of the `Thread.Sleep` in your async callback? Second, are you certain that the callback is actually being executed multiple times? It seems unlikely that your client will receive "S0000" when the sender sends "S8000". – Jim Mischel Aug 17 '15 at 18:11
  • Also see http://stackoverflow.com/questions/7266101/receive-messages-continuously-using-udpclient for a simple UDP receiver. – Jim Mischel Aug 17 '15 at 18:17
  • I just add the thread.sleep to give break of 150 milliseconds because of this I started to receive accurate data. I have seen your comments in the answers http://stackoverflow.com/questions/7266101/receive-messages-continuously-using-udpclient and based on those suggestion I have removed Thread.sleep and calling BeginReceive right after endreceive but its working really fast and during the processing of data it recorded as empty string but data actually came in! – dawncode Aug 18 '15 at 07:53
  • As I'm processing the data I'm continuously receiving new data which is causing problem.. Is there any way to put barrier to look for new data once done the processing. – dawncode Aug 24 '15 at 07:46

1 Answers1

0

The main difference in your UDPListener and while loop is that in loop you are creating udp variable each time you are connecting to the UDP:

 udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);

In Receive(IAsyncResult ar) you only connect with the same client, so you still have the same data.
I think that you can rewrite your class something like this:

private void StartListening()
{
    udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);
    ar_ = udp.BeginReceive(Receive, new object());
}

Make sure that you're disposing the udp connection after receive with Close() method:

byte[] bytes = udp.EndReceive(ar, ref ip);
udp.Close();
VMAtm
  • 27,943
  • 17
  • 79
  • 125