使用C#插槽发现Lantronix XPort Pro和XPort

时间:2018-07-10 16:52:37

标签: c# sockets

我正在尝试使用C#在网络上查找Lantronix XPort Pro设备。我使用在Lantronix开发人员Wiki上找到的一些python代码作为示例http://wiki.lantronix.com/developer/Lantronix_Discovery_Protocol

我正在编写的应用程序是用C#编写的,我需要发现安装了Lantronix设备的设备。看来,当我执行socket.RecieveFrom函数调用时,似乎只是挂了该应用程序。

关于我在做什么的任何想法。上面链接中的python代码可以正确检测设备。我应该可以在C#中复制它。

任何帮助将不胜感激。

   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();
    }

2 个答案:

答案 0 :(得分:1)

Lantronix的wiki目前似乎已关闭,因此我暂时无法对此进行介绍。但是,查看您的代码似乎必须广播UDP消息,等待一段时间,然后检查是否有任何响应该消息的消息。

但是,看起来您正在创建一个全新的套接字来接收响应,但仅需半秒钟。在那之前很长时间,任何将要响应的X端口都已经做完了(网络速度很快,X端口不是很慢,等等)。因此,我认为响应正在触及您操作系统的网络堆栈,上面写着“好吧,我不知道应该去哪儿”,只有半秒钟之后,您才创建一个适合接收操作系统网络堆栈响应的套接字已经被当作未知垃圾丢弃了。

因此,我建议您稍微调整一下。在传输广播消息之前,先设置接收套接字,绑定和端点 ,以便在该处准备好等待响应。看看是否有帮助。

答案 1 :(得分:1)

@WJD您用于准备字节数组的代码未创建XPort期望的内容。这就是为什么它没有回复并挂在RecieveFrom()上的原因。 我按照您为python示例提供的链接并在C#中创建了版本。

class Program
{
    static void Main(string[] args)
    {
        Socket socket;
        int GroupPort = 30718;
        try
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
            var localEP = new IPEndPoint(IPAddress.Parse("10.0.2.14"), GroupPort);    // <-- your local IP address

            socket.Bind(localEP);
            socket.ReceiveTimeout = 200;
        }
        catch (TimeoutException e)
        {
            Console.WriteLine("Failed to create socket. " + e.Message);
            return;
        }


        var remoteEP = new IPEndPoint(IPAddress.Broadcast, GroupPort);
        try
        {
            byte[] messageBytes;
            messageBytes = new byte[0];
            messageBytes = AddByteToArray(messageBytes, 0xf6);
            messageBytes = AddByteToArray(messageBytes, 0);
            messageBytes = AddByteToArray(messageBytes, 0);
            messageBytes = AddByteToArray(messageBytes, 0);

            socket.SendTo(messageBytes, remoteEP);
        }
        catch (Exception e)
        {
            Console.WriteLine("Failed to send message. " + e.Message);
            return;
        }


        var recvEp = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
        while (true)
        {
            try
            {
                var recvBytes = new byte[1024];
                var receivedCount = socket.ReceiveFrom(recvBytes, ref recvEp);
                var receivedArray = recvBytes.Take(receivedCount).ToArray();
                var receivedArrayAsHexString = string.Join("", receivedArray.Select(c => String.Format("{0:X2}", Convert.ToInt32(c))));
                string returnData = Encoding.ASCII.GetString(receivedArray);
                Console.WriteLine($"Broadcast Respond from client {recvEp.ToString()} returned: {receivedArrayAsHexString}");
            }
            catch (Exception e)
            {
                socket.Close();
                break;
            }
        }
        Console.ReadLine();
    }

    public static byte[] AddByteToArray(byte[] bArray, byte newByte)
    {
        byte[] newArray = new byte[bArray.Length + 1];
        bArray.CopyTo(newArray, 1);
        newArray[0] = newByte;
        return newArray;
    }

}