我正在尝试使用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();
}
目前Lantronix的维基似乎已经失败了,所以我暂时无法看到它。但是,查看您的代码似乎您必须广播UDP消息,等待一段时间,然后检查是否有任何响应该消息。
但是,看起来你正在创建一个全新的套接字来接收响应,但仅在半秒之后。很可能任何响应的X端口在此之前很久就已经完成了(网络速度很快,X端口不是很迟钝等等)。所以我认为响应正在击中你的操作系统网络堆栈,其中说“好吧我不知道应该去哪里”,并且只有半秒后你才创建一个适合接收OS网络堆栈响应的套接字已经丢弃了作为未知的垃圾。
因此,我建议将事情移动一下。在发送广播消息之前设置接收套接字,绑定和端点,以便它在那里等待响应。看看是否有帮助。
@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;
}
}