C#通过udp组播实现同网段内设备发现
项目需求:
能够发现局域网中所有已经连接的设备,找到并显示设备的ip、MAC、状态及端口等信息。
udp组播之前没有接触过,通过网上找到的解决方案及自己在实际项目中测试,最后实现代码大致如下:
private static UdpClient _UdpClient;//声明udp客户端
public event Action<Multicast> OnUdpMulticast;//定义处理数据事件
private const int _RemotePort = 8161;//组播端口(根据需要修改)
private const string _RemoteIP = "230.1.1.168";//组播组地址(根据需要修改)
private bool _IsMulticast = false;//是否循环检测标识
Task taskUdp = new Task(() => { try {
IPAddress remoteAddress = IPAddress.Parse(_RemoteIP);//转换标准IPAddress _UdpClient = new UdpClient(_RemotePort);//创建udp客户端 _UdpClient.JoinMulticastGroup(remoteAddress);//加入组播组 IPEndPoint ipeRemote = new IPEndPoint(remoteAddress, _RemotePort);//定义远程发送组播消息端点信息 while (_IsMulticast) { byte[] recvBuffer = _UdpClient.Receive(ref ipeRemote);//接收组播组数据 if (recvBuffer != null) { string recvStr = Encoding.UTF8.GetString(recvBuffer);//转为字符串 string jsonStr = ToJson(recvStr);//将接收的字符串转为标准json字符串 Multicast multicast = ConvertHelper.JsonToModel<Multicast>(jsonStr);//调用封装Newtosoft函数转实体类 TriggerOnUdpMulticast(multicast);//触发事件方法 } Thread.Sleep(500);//休眠 } } catch (Exception ex) { LogManager.log(ex.StackTrace); } }); taskUdp.Start();
//触发事件方法
private void TriggerOnUdpMulticast(Multicast msg)
{
OnUdpMulticast?.Invoke(msg);
}
//接收到的组播消息为非标准json,缺少大括号和双引号,这里做转换处理(根据实际消息处理)
private string ToJson(string msg)
{
if (!msg.StartsWith("^") || !msg.EndsWith("$"))
return string.Empty;
msg = msg.TrimStart('^').TrimEnd('$').ToUpper();
string[] paramArray = msg.Split(',');
StringBuilder sbJson = new StringBuilder();
foreach (string text in paramArray)
{
string[] keyValue = text.Trim().Split(':');
string key;
if (keyValue.Length != 2 || (key = keyValue[0]) == null)
return string.Empty;
sbJson.Append($"\"{key}\":\"{keyValue[1]}\",");
}
sbJson.Remove(sbJson.Length - 1, 1);
string jsonStr = $"{{{sbJson.ToString()}}}";
return jsonStr;
}