C#如何使用UDP广播实现局域网设备发现与寻址

来源:站长工具作者:小何头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#如何使用UDP广播实现局域网设备发现与寻址》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何使用UDP广播实现局域网设备发现与寻址》有用,将其分享出去将是对创作者最好的鼓励。

UDP广播是局域网内设备快速通信的重要手段,它不需要建立稳定的连接,就能将消息同时发送给网段内的所有设备,非常适合设备发现、状态通知这类场景。在C#中可以通过System.Net.Sockets命名空间下的Socket类实现UDP广播的发送和接收,完成局域网内设备的寻址与发现功能。

C#如何使用UDP广播实现局域网设备发现与寻址

UDP广播核心原理

UDP广播的地址范围是255.255.255.255,发送到这个地址的数据包会被局域网内所有设备接收。设备发现的基本流程是:待发现的设备定时向广播地址发送包含自身信息的广播包,需要发现设备的客户端监听指定端口,收到广播包后解析出设备信息,完成寻址。

广播发送端实现(设备端)

设备端需要定时向广播地址发送自身信息,比如设备ID、IP地址、服务端口等,代码如下:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace UdpBroadcaster
{
    class DeviceBroadcaster
    {
        // 广播端口,发送和接收端需要保持一致
        private const int BROADCAST_PORT = 11000;
        // 广播间隔,单位毫秒
        private const int BROADCAST_INTERVAL = 2000;
        // 设备唯一标识
        private string deviceId;
        // 设备提供的服务端口
        private int servicePort;

        public DeviceBroadcaster(string deviceId, int servicePort)
        {
            this.deviceId = deviceId;
            this.servicePort = servicePort;
        }

        public void StartBroadcast()
        {
            // 创建UDP Socket
            using (Socket broadcastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                // 设置广播权限
                broadcastSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                // 广播地址
                IPEndPoint broadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, BROADCAST_PORT);
                
                while (true)
                {
                    try
                    {
                        // 构造广播消息,格式:设备ID|设备IP|服务端口
                        string localIp = GetLocalIPAddress();
                        string message = $"{deviceId}|{localIp}|{servicePort}";
                        byte[] sendData = Encoding.UTF8.GetBytes(message);
                        // 发送广播
                        broadcastSocket.SendTo(sendData, broadcastEndPoint);
                        Console.WriteLine($"已发送广播消息:{message}");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"广播发送失败:{ex.Message}");
                    }
                    // 等待下一个广播周期
                    Thread.Sleep(BROADCAST_INTERVAL);
                }
            }
        }

        // 获取本地局域网IP地址
        private string GetLocalIPAddress()
        {
            var host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    return ip.ToString();
                }
            }
            return "127.0.0.1";
        }
    }
}

广播接收端实现(客户端)

客户端需要监听指定的广播端口,接收设备发送的广播消息并解析出设备信息,代码如下:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;

namespace UdpReceiver
{
    class DeviceDiscoverer
    {
        // 监听的广播端口,需要和发送端一致
        private const int LISTEN_PORT = 11000;
        // 存储发现的设备信息
        private Dictionary<string, DeviceInfo> discoveredDevices = new Dictionary<string, DeviceInfo>();

        public void StartDiscovery()
        {
            // 创建UDP Socket
            using (Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                // 绑定监听端口
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, LISTEN_PORT);
                listenSocket.Bind(localEndPoint);
                // 远程端点,用于接收数据时获取发送方信息
                EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);

                Console.WriteLine($"开始监听广播端口 {LISTEN_PORT}...");

                while (true)
                {
                    try
                    {
                        // 接收数据缓冲区
                        byte[] receiveData = new byte[1024];
                        int receiveLength = listenSocket.ReceiveFrom(receiveData, ref remoteEndPoint);
                        string message = Encoding.UTF8.GetString(receiveData, 0, receiveLength);
                        // 解析设备信息
                        ParseDeviceMessage(message, remoteEndPoint as IPEndPoint);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"接收广播失败:{ex.Message}");
                    }
                }
            }
        }

        // 解析接收到的设备消息
        private void ParseDeviceMessage(string message, IPEndPoint remoteEndPoint)
        {
            if (string.IsNullOrEmpty(message))
            {
                return;
            }
            string[] parts = message.Split('|');
            if (parts.Length != 3)
            {
                return;
            }
            string deviceId = parts[0];
            string deviceIp = parts[1];
            int servicePort;
            if (!int.TryParse(parts[2], out servicePort))
            {
                return;
            }
            // 更新设备信息,避免重复添加
            if (!discoveredDevices.ContainsKey(deviceId))
            {
                discoveredDevices.Add(deviceId, new DeviceInfo
                {
                    DeviceId = deviceId,
                    DeviceIp = deviceIp,
                    ServicePort = servicePort,
                    LastActiveTime = DateTime.Now
                });
                Console.WriteLine($"发现新设备:ID={deviceId}, IP={deviceIp}, 服务端口={servicePort}");
            }
            else
            {
                discoveredDevices[deviceId].LastActiveTime = DateTime.Now;
            }
        }

        // 获取当前发现的设备列表
        public List<DeviceInfo> GetDiscoveredDevices()
        {
            return new List<DeviceInfo>(discoveredDevices.Values);
        }
    }

    // 设备信息实体类
    class DeviceInfo
    {
        public string DeviceId { get; set; }
        public string DeviceIp { get; set; }
        public int ServicePort { get; set; }
        public DateTime LastActiveTime { get; set; }
    }
}

注意事项

  • 广播端口需要发送端和接收端保持一致,且不能被其他程序占用,建议选择1024以上的端口。
  • 局域网内的防火墙可能会拦截UDP广播包,测试时需要关闭对应防火墙规则或者添加端口例外。
  • 如果需要区分不同网段的设备,需要调整广播地址,避免广播包被路由器转发到公网。
  • 设备信息可以扩展更多字段,比如设备名称、设备类型、支持的服务列表等,根据实际需求调整消息格式即可。

使用示例

设备端启动代码:

class Program
{
    static void Main(string[] args)
    {
        // 初始化设备广播器,设备ID为DEV001,服务端口为8080
        DeviceBroadcaster broadcaster = new DeviceBroadcaster("DEV001", 8080);
        broadcaster.StartBroadcast();
    }
}

客户端启动代码:

class Program
{
    static void Main(string[] args)
    {
        DeviceDiscoverer discoverer = new DeviceDiscoverer();
        discoverer.StartDiscovery();
    }
}

C#UDP广播局域网设备发现Socket编程设备寻址修改时间:2026-06-16 01:09:25

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。