0

I am trying to auto find server app within a local network using usbclient in the following code. the sever and broadcaster is run on separate pc. The server always receives the broadcaster message, but the broadcaster doesn't or sometimes receives message only once.

//////////////////////
// UDP BROADCASTER //
//////////////////////
static void Main(string[] args)
{
    const string addr = "224.0.0.1";
    const int prt = 5555;

    UdpClient udpc = new UdpClient();
    udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    var LocalIP = GetLocalIPAddress();
    Console.WriteLine($"LocalIP: {LocalIP}");

    udpc.Client.Bind(new IPEndPoint(IPAddress.Parse(LocalIP), prt));
    // Enable broadcast.
    udpc.EnableBroadcast = false;
    // Disable multicast loopback.
    udpc.MulticastLoopback = false;
    udpc.JoinMulticastGroup(IPAddress.Parse(addr));
    System.Threading.ManualResetEvent abort = new ManualResetEvent(false);
    WaitHandle[] evs = new WaitHandle[2];
    evs[0] = abort;
    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
    {
        while (true)
        {
            IAsyncResult asy = udpc.BeginReceive(
            new AsyncCallback(delegate (IAsyncResult iasy)
            {
                IPEndPoint rp = null;
                byte[] recv = udpc.EndReceive(iasy, ref rp);
                string data = Encoding.ASCII.GetString(recv);
                Console.WriteLine($"recv {data} from {rp.ToString()}");
            }), null);
            evs[1] = asy.AsyncWaitHandle;
            if (WaitHandle.WaitAny(evs) == 0) return;
        }
    }));
    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
    {
        for (int i = 0; i < 100; i++)
        {
            var msg = $"Hello {i}";
            var byts = ASCIIEncoding.ASCII.GetBytes(msg);//new byte[] { 0x1, 0x2 };
                udpc.Send(byts, byts.Length, new IPEndPoint(IPAddress.Parse(addr), prt));
            Console.WriteLine($"Sent: {msg}");
            Thread.Sleep(2000);
            if (abort.WaitOne(0, false)) return;
        }
    }));
    Console.Read();
    abort.Set();
}
/////////////////
// UDP SERVER //
////////////////
static void Main(string[] args)
{
    const string addr = "224.0.0.1";
    const int prt = 5555;

    UdpClient udpc = new UdpClient();
    udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    //udpc.Client.Bind(new IPEndPoint(IPAddress.Any, prt));
    var LocalIP = GetLocalIPAddress();
    Console.WriteLine($"LocalIP: {LocalIP}");
    udpc.Client.Bind(new IPEndPoint(IPAddress.Parse(LocalIP), prt));
    udpc.JoinMulticastGroup(IPAddress.Parse(addr));
    System.Threading.ManualResetEvent abort = new ManualResetEvent(false);
    WaitHandle[] evs = new WaitHandle[2];
    evs[0] = abort;
    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
    {
        while (true)
        {
            IAsyncResult asy = udpc.BeginReceive(
            new AsyncCallback(delegate (IAsyncResult iasy)
            {
                IPEndPoint rp = null;
                byte[] recv = udpc.EndReceive(iasy, ref rp);
                string data = Encoding.ASCII.GetString(recv);
                Console.WriteLine($"{DateTime.Now.TimeOfDay} recv {data} from {rp.ToString()}");
                var byts = ASCIIEncoding.ASCII.GetBytes($"Ip:: {LocalIP} MachineName: {Environment.MachineName}");
                udpc.Send(byts, byts.Length, rp);

            }), null);
            evs[1] = asy.AsyncWaitHandle;
            if (WaitHandle.WaitAny(evs) == 0) return;
        }
    }));

    Console.Read();
    abort.Set();
}

any ideas or recommendation is welcome

6
  • "but the broadcaster doesn't or sometimes receives message only once" - yep. UDP is unreliable by design. You must anticipate missing packets, out-of-order packets and maybe even duplicate packets. Now, I don't know why you are not sending from a timer, simply, but alas. If A->B works more reliable than B->A, then there pretty probably should be a difference. Can you spot one? Commented Jan 10, 2024 at 11:49
  • no i cannot spot the error, pls point it out Commented Jan 10, 2024 at 11:58
  • :-) It was an honest question, I didn't mean to sound condescending. I was hoping you could point out a difference being "closer" to the code ... :) Commented Jan 10, 2024 at 12:01
  • What jumps to my eye (but may actually be valid): In your broadcaster you have a comment // Enable broadcast and in the next line, you disable broadcasts ... Commented Jan 10, 2024 at 12:04
  • I faintly remember doing something similar (but in Java). I think, if I remember correctly, I had 2 Ports: Port A for Clients to trigger the Server to send a Beacon and Port B for the Clients to listen for that Beacon. So, Server would 1. Every X amount of time send a Beacon unconditionally ("KeepAlive") and 2. Upon receiving a trigger: a) stop listening for the trigger for X amount of time, b) would send out X number of Beacon packets, then after Y amount of time X/10 number of Beacons, then after Y*10 amount of time X/100 Beacons and after Y * 100 amount of time listen for triggers again. Commented Jan 10, 2024 at 12:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.