using System; using System.Collections.Generic; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace EC.Onvif.RemoteDiscovery { public class OnvifUdpClient { private UdpClient client { get; set; } public bool IsClosed { get; set; } public OnvifUdpClient(IPEndPoint localpoint) { client = new UdpClient(localpoint) { EnableBroadcast = true }; } public async Task SendProbeAsync(Guid messageId, IPEndPoint endPoint) { byte[] datagram = NewProbeMessage(messageId); return await client?.SendAsync(datagram, datagram.Length, endPoint); } public async Task ReceiveAsync() { return await client.ReceiveAsync(); } public void Close() { client?.Close(); IsClosed = true; } public static byte[] NewProbeMessage(Guid messageId) { if (messageId == Guid.Empty) { throw new ArgumentException("messageId could not be Empty"); } var probeMessagewithguid = string.Format(Constants.WS_PROBE_MESSAGE, messageId.ToString()); return Encoding.ASCII.GetBytes(probeMessagewithguid); } #region CreateClient public static OnvifUdpClient CreateClient(NetworkInterface adapter) { if (!IsValidAdapter(adapter)) { return null; } OnvifUdpClient client = null; IPInterfaceProperties adapterProperties = adapter.GetIPProperties(); foreach (UnicastIPAddressInformation ua in adapterProperties.UnicastAddresses) { if (ua.Address.AddressFamily != AddressFamily.InterNetwork) { continue; } IPEndPoint myLocalEndPoint = new(ua.Address, 0); // port does not matter try { client = new(myLocalEndPoint); } catch (SocketException) { throw; } break; } return client; } public static IEnumerable CreateClientList(IEnumerable adapterList) { List clientList = new(); foreach (NetworkInterface adapter in adapterList) { OnvifUdpClient client = CreateClient(adapter); if (client != null) { clientList.Add(client); } } return clientList; } public static IEnumerable CreateClientList() { IEnumerable adapterList = GetVaildNetworkAdapters(); return CreateClientList(adapterList); } #endregion CreateClient #region ClientHelper public static List GetNetworkAdapters() { NetworkInterface[] nifs = NetworkInterface.GetAllNetworkInterfaces(); return new(nifs); } public static List GetVaildNetworkAdapters() { NetworkInterface[] nifs = NetworkInterface.GetAllNetworkInterfaces(); List list = new(); foreach (NetworkInterface nif in nifs) { if (IsValidAdapter(nif)) { list.Add(nif); } } return list; } public static bool IsValidAdapter(NetworkInterface adapter) { // Only select interfaces that are Ethernet type and support IPv4 (important to minimize waiting time) if (adapter.NetworkInterfaceType != NetworkInterfaceType.Ethernet && !adapter.NetworkInterfaceType.ToString().ToLower().StartsWith("wireless")) return false; if (adapter.OperationalStatus == OperationalStatus.Down) { return false; } if (!adapter.Supports(NetworkInterfaceComponent.IPv4)) { return false; } return true; } /// /// 广播 /// /// /// /// public static async Task SendProbe(OnvifUdpClient client, Guid messageId) { IPEndPoint multicastEndpoint = new(IPAddress.Parse(Constants.WS_MULTICAST_ADDRESS), Constants.WS_MULTICAST_PORT); await client.SendProbeAsync(messageId, multicastEndpoint); } #endregion ClientHelper } }