using Apewer.Internals; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; namespace Apewer.Network { /// UDP 客户端。 public static class UdpClient { /// 向所有服务端广播数据。 /// 数据。 /// 服务端端口。 public static bool Broadcast(byte[] bytes, int port) { if (bytes == null) return false; if (bytes.LongLength == 0) return false; if (port < 0) port = 0; if (port > 65535) port = 65535; try { var uc = new System.Net.Sockets.UdpClient(); var ep = new IPEndPoint(IPAddress.Parse("255.255.255.255"), port); uc.EnableBroadcast = true; uc.Send(bytes, bytes.Length, ep); uc.Close(); return true; } catch { return false; } } /// 向指定服务端发送数据。 /// 服务端 IP 地址。 /// 服务端端口。 /// 数据。 /// 阻塞当前线程,等待服务端返回数据,指定 FALSE 将立刻返回 NULL 值。 /// 服务器返回的数据。当通过 await 参数指定 FALSE 时,立刻返回 NULL 值。 public static byte[] Send(string ip, int port, byte[] bytes, bool await = false) { if (bytes == null) return null; if (bytes.LongLength == 0) return null; if (port < 0) port = 0; if (port > 65535) port = 65535; try { var uc = new System.Net.Sockets.UdpClient(); var ep = new IPEndPoint(IPAddress.Parse(ip), port); uc.EnableBroadcast = false; uc.Send(bytes, bytes.Length, ep); var received = null as byte[]; if (await) { var rep = null as IPEndPoint; received = await ? uc.Receive(ref rep) : null; } uc.Close(); return received; } catch { return null; } } /// 向指定服务端发送数据。 /// 服务端 IP 地址。 /// 服务端端口。 /// 数据。 /// 阻塞当前线程,等待服务端返回数据,指定 FALSE 将立刻返回 NULL 值。 /// 服务器返回的数据。当通过 await 参数指定 FALSE 时,立刻返回 NULL 值。 public static byte[] Send(byte[] bytes, int port, string ip = "127.0.0.1", bool await = false) { return Send(ip, port, bytes, false); } /// 向指定服务端发送数据。 /// 服务端 IP 地址。 /// 服务端端口。 /// 数据。 /// 阻塞当前线程,等待服务端返回数据,指定 FALSE 将立刻返回 NULL 值。 /// 服务器返回的数据。当通过 await 参数指定 FALSE 时,立刻返回 NULL 值。 public static byte[] Send(int port, byte[] bytes, string ip = "127.0.0.1", bool await = false) { return Send(ip, port, bytes, false); } /// 唤醒局域网中拥有指定 MAC 地址的设备。 /// 被唤醒设备的 MAC 地址,必须是长度为 6 的字节数组。 public static void WakeOnLan(byte[] mac) { if (mac.Length != 6) return; var uc = new System.Net.Sockets.UdpClient(); uc.Connect(IPAddress.Broadcast, 65535); var pack = new List(); // 前 6 字节为 0xFF。 for (int i = 0; i < 6; i++) pack.Add(255); // 目标 MAC 地址重复 16 次。 for (int i = 0; i < 16; i++) { for (int j = 0; j < 6; j++) pack.Add(mac[j]); } // 发送 102 字节数据。 uc.Send(pack.ToArray(), pack.Count); uc.Close(); } } }