Search code examples
c#sockets

Discovering Lantronix XPort Pro and XPort using C# sockets


I am trying to find Lantronix XPort Pro devices on a network using C#. I am using some python code that I found on the Lantronix developer wiki as an example http://wiki.lantronix.com/developer/Lantronix_Discovery_Protocol.

The application I am writing is written in C# and I need to discover our units that have Lantronix devices installed. It seems that when I do the socket.RecieveFrom function call it just seems to hang the app.

Any ideas on what I am doing wrong. The python code from the link above detects the devices correctly. I should be able to duplicate this in C#.

Any help would be much appreciated.

   private void FindLantronixXPort()
    {
        // This is the socket code that will broadcast from 
        // the local machine looking for responces from Lantronix
        // XPort servers

        // Create the array for our message chars
        char[] chars = new char[4];

        // Build the actual message
        chars[0] = Convert.ToChar(0);
        chars[1] = Convert.ToChar(0);
        chars[2] = Convert.ToChar(0);
        chars[3] = Convert.ToChar(0xf6);

        // Convert the chars to a message string
        string msg = new string(chars);

        // Convert the setring to a byte array
        byte[] data = Encoding.UTF8.GetBytes(msg);

        // Get the local machines IP address
        string Local_IP = GetIPAddress();

        // Now create a broadcast UDP socket
        Socket XmtSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        XmtSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

        IPEndPoint iep = new IPEndPoint(IPAddress.Parse(Local_IP), LantronixPort);

        // Broadcast the packet
        XmtSock.SendTo(data, 0, data.Length, SocketFlags.None, iep);

        XmtSock.Close();

        // Wait 500 mili seconds
        int milliseconds = 500;
        System.Threading.Thread.Sleep(milliseconds);

        Socket RcvSock = new Socket(AddressFamily.InterNetwork,
            SocketType.Dgram, ProtocolType.Udp);

        iep = new IPEndPoint(IPAddress.Any, LantronixPort);

        RcvSock.Bind(iep);

        EndPoint ep = (EndPoint)iep;

        Console.WriteLine("Ready to receive...");

        byte[] data1 = new byte[120];

        int recv = RcvSock.ReceiveFrom(data1, data1.Length, SocketFlags.None, ref ep);

        string stringData = Encoding.ASCII.GetString(data1, 0, recv);

        Console.WriteLine("received: {0}  from: {1}",
                              stringData, ep.ToString());

        RcvSock.Close();
    }

Solution

  • Lantronix's wiki seems to be down at the moment, so I can't take a look at that for the moment. However, looking at your code it seems that you have to broadcast a UDP message, wait some time, and then check to see if anything has responded to that message.

    However, it looks like you're creating a brand new socket for receiving the responses, but only after half a second. It's highly likely that any X-port that is going to respond will already have done so long before then (networks are fast, X-ports aren't very sluggish, etc). So I reckon the responses are hitting your OS'es network stack, which saying "well I dunno where that's supposed to go", and only after half a second are you creating a socket suitable for receiving the responses that the OS'es network stack has already discarded as unknown junk.

    So move things around a bit is what I suggest. Set up the receiving socket, binding and endpoint before you transmit the broadcast message, so that it's ready there waiting for responses. See if that helps.