using ServerManagement.Models;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
namespace ServerManagement.Common
{
public class WakeOnLan
{
/// <summary>
/// 发送唤醒数据包
/// </summary>
/// <param name="broadcastAddress">广播地址</param>
/// <param name="port">端口号</param>
/// <param name="macAddress">MAC地址</param>
public static ResultModel Wake(string broadcastAddress, int port, string macAddress)
{
ResultModel result= new ResultModel();
try
{
// 清理MAC地址格式
string cleanMac = CleanMacAddress(macAddress);
// 验证MAC地址
if (!IsValidMacAddress(cleanMac))
{
result.code = 2;
result.msg = $"无效的MAC地址: {macAddress}";
}
// 将MAC地址转换为字节数组
byte[] macBytes = MacStringToBytes(cleanMac);
// 构造魔术数据包
byte[] magicPacket = CreateMagicPacket(macBytes);
// 发送数据包
SendMagicPacket(broadcastAddress, port, magicPacket);
result.code = 1;
result.msg = $"唤醒数据包发送完成 {broadcastAddress}:{port} MAC:{macAddress}";
}
catch (Exception ex)
{
result.code = 2;
result.msg = $"发送唤醒数据包失败: {ex.Message}";
}
return result;
}
/// <summary>
/// 清理MAC地址格式(移除分隔符)
/// </summary>
private static string CleanMacAddress(string macAddress)
{
if (string.IsNullOrWhiteSpace(macAddress))
return string.Empty;
// 移除所有分隔符和空格
return Regex.Replace(macAddress, @"[:\-\.\s]", "").ToUpper();
}
/// <summary>
/// 验证MAC地址格式
/// </summary>
private static bool IsValidMacAddress(string macAddress)
{
if (string.IsNullOrWhiteSpace(macAddress) || macAddress.Length != 12)
return false;
// 检查是否为有效的十六进制字符串
return Regex.IsMatch(macAddress, @"^[0-9A-F]{12}$");
}
/// <summary>
/// 将MAC地址字符串转换为字节数组
/// </summary>
private static byte[] MacStringToBytes(string macAddress)
{
byte[] macBytes = new byte[6];
for (int i = 0; i < 6; i++)
{
string hex = macAddress.Substring(i * 2, 2);
macBytes[i] = Convert.ToByte(hex, 16);
}
return macBytes;
}
/// <summary>
/// 构造魔术数据包
/// </summary>
/// <remarks>
/// 魔术数据包格式:6字节0xFF + 16次MAC地址
/// </remarks>
private static byte[] CreateMagicPacket(byte[] macBytes)
{
// 数据包大小:6字节的0xFF + 16 * 6字节的MAC地址 = 102字节
byte[] packet = new byte[102];
// 前6字节填充0xFF
for (int i = 0; i < 6; i++)
{
packet[i] = 0xFF;
}
// 重复16次MAC地址
for (int i = 0; i < 16; i++)
{
Array.Copy(macBytes, 0, packet, 6 + i * 6, 6);
}
return packet;
}
/// <summary>
/// 发送魔术数据包
/// </summary>
private static void SendMagicPacket(string broadcastAddress, int port, byte[] magicPacket)
{
using (UdpClient client = new UdpClient())
{
// 启用广播
client.EnableBroadcast = true;
// 发送到指定地址和端口
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(broadcastAddress), port);
client.Send(magicPacket, magicPacket.Length, endPoint);
}
}
}
}//ResultModel实体类
public class xResultModel
{
public int code = 1;
public string? msg { get; set; }
}方法调用
WakeOnLan.Wake("255.255.255.255", 7, "3cecefeb0412");注意:需先设置 PC 主板和系统支持网口唤醒;关机状态下,网口指示灯需保持闪烁(说明网口处于通电状态)。
本文来自 www.luofenming.com