使用C#套接字发现Lantronix XPort Pro和XPort

问题描述 投票:2回答:2

我正在尝试使用C#在网络上找到Lantronix XPort Pro设备。我使用一些我在Lantronix开发人员维基上找到的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();
    }
c# sockets
2个回答
1
投票

目前Lantronix的维基似乎已经失败了,所以我暂时无法看到它。但是,查看您的代码似乎您必须广播UDP消息,等待一段时间,然后检查是否有任何响应该消息。

但是,看起来你正在创建一个全新的套接字来接收响应,但仅在半秒之后。很可能任何响应的X端口在此之前很久就已经完成了(网络速度很快,X端口不是很迟钝等等)。所以我认为响应正在击中你的操作系统网络堆栈,其中说“好吧我不知道应该去哪里”,并且只有半秒后你才创建一个适合接收OS网络堆栈响应的套接字已经丢弃了作为未知的垃圾。

因此,我建议将事情移动一下。在发送广播消息之前设置接收套接字,绑定和端点,以便它在那里等待响应。看看是否有帮助。


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

}

推荐问答