zoukankan      html  css  js  c++  java
  • .NET远程开机

      应网友gx0754的建议将本软件进行了一些小改动,增加了历史记录功能。

      

      下载WakeOnLAN.zip

      之前,在家鼓弄BIOS时,知道了电脑可以远程开机,实际上就是利用网卡唤醒,学名呢,叫Wake-On-LAN,WOL。这技术比较早了,现在的板载网卡和普通网卡基本上全支持,有些需要在BIOS中设置。打开Wake On LAN和PWE功能。

    这是我电脑的设置:

     

    然后在操作系统里对网卡进行设置,打开设备管理器,选网卡,在高级选项卡中设置,如图:

    如果你没有那些选项,你可以尝试更新一下网卡驱动。

    网上说电源管理里的“允许这台设备使计算机脱离待机状态”要选上,其实不选也可以的。

    根据经验,一定要在开机后,选择系统里的关机,才能实现远程开机,断电后就不灵了。实际上应该叫唤醒才对,关机后计算机进入S4模式,然后通过网卡唤醒。

    接下来就是软件的事了,网上有不少,可以自己搜的,但我自己根据原理写了一个,测试没问题。

    有兴趣可以下来玩玩(含源码,虽然自己的水平很差,但我相信肯定有比我更差的……囧)

    WakeOnLAN.zip 单编写了一个WakeOnLAN类库,如果用的上的可以直接拿来用,包含计算广播地址,通过IP得到MAC地址等实用的功能。

    简单的说就是向一个网络内发送Magic Package(一串特殊的序列)。据个例子解释一下,FF FF FF FF FF FF | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66 | 11 22 33 44 55 66,6byte的同步信号,这部分时不变的全是FF,接下来是重复16次MAC地址,很简单吧。之后通过UDP方式广播到子网,符合MAC地址的主机就会执行开机命令。


     

    第一次贴代码,大家见笑了。

     

    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    /// <summary>
    /// 远程唤醒
    /// </summary>
    public class WakeOnLAN
    {
        public enum NetType
        {
            Internet,
            Subnet
        }
        
        private static UdpClient listener;
    
        public WakeOnLAN()
        {
    
        }
    
        /// <summary>
        /// 域名转换为IP地址
        /// </summary>
        /// <param name="hostname">域名或IP地址</param>
        /// <returns>IP地址</returns>
        public static string Hostname2ip(string hostname)
        {
            IPAddress ip;
            if (IPAddress.TryParse(hostname, out ip))
            {
                return ip.ToString();
            }
            else
            {
                return Dns.GetHostEntry(hostname).AddressList[0].ToString();
            }
        }
    
        /// <summary>
        /// 处理监听到的数据的方法
        /// </summary>
        /// <param name="bytes">接收到的数据</param>
        /// <param name="groupEP">接收地址</param>
        public delegate void ListenerHandler(byte[] bytes, IPEndPoint groupEP);
    
        /// <summary>
        /// 当监听到数据报
        /// </summary>
        public static event ListenerHandler Listened;
    
        /// <summary>
        /// UDP监听器
        /// </summary>
        /// <param name="port">端口号</param>
        public static void Listener(object port)
        {
            listener = new UdpClient((int)port);
            IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, (int)port);
            try
            {
                while (true)
                {
                    byte[] bytes = listener.Receive(ref groupEP);
                    Listened(bytes, groupEP);
                }
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            finally
            {
                listener.Close();
            }
        }
    
        private static Thread thd;
        /// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="port">要监听的端口号</param>
        public static void StartListener(int port)
        {
            thd = new Thread(new ParameterizedThreadStart(WakeOnLAN.Listener));
            thd.Start(port);
        }
    
        /// <summary>
        /// 停止监听
        /// </summary>
        public static void StopListener()
        {
            listener.Close();
            thd.Abort();
        }
    
        /// <summary>
        /// 唤醒远程主机
        /// </summary>
        /// <param name="macAddress">MAC地址</param>
        /// <param name="ipAddress">IP地址</param>
        /// <param name="subnetMask">子网掩码</param>
        /// <param name="portNo">端口号</param>
        /// <param name="nt">网络类型</param>
        /// <returns>发送结果</returns>
        public static string WakeUp(string macAddress, string ipAddress, string subnetMask, string portNo, NetType nt)
        {
            IPAddress ip;
            IPAddress subnet;
            if (!IPAddress.TryParse(ipAddress.Replace(" ", ""), out ip))
                return "IP Address error";
            if (!IPAddress.TryParse(subnetMask, out subnet))
                return "Subnet Mask error";
            if (macAddress.Length != 17)
                return "MAC Address error";
    
            int port;
            if (int.TryParse(portNo, out port) && (1 <= port && port <= 65535))
            {
                string broadcast = GetBroadcast(ip, subnet, nt);
                return "Send to " + SendMagicPackage(broadcast, port, macAddress) + ":" + portNo;
            }
            else
            {
                return "Port Number error";
            }
        }
    
        [DllImport("Iphlpapi.dll")]
        private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
        [DllImport("Ws2_32.dll")]
        private static extern Int32 inet_addr(string ip);
    
        /// <summary>
        /// 通过IP地址获取MAC(同一网段内)
        /// </summary>
        /// <param name="ipAddress">IP地址</param>
        /// <returns>MAC地址</returns>
        public static string GetMacAddress(string ipAddress)
        {
            IPAddress ip;
            if (!IPAddress.TryParse(ipAddress.Replace(" ", ""), out ip))
                return "IP Address error";
    
            Int32 ldest = inet_addr(ip.ToString());
            Int64 macinfo = new Int64();
            StringBuilder macAddress = new StringBuilder();
            try
            {
                Int32 len = 6;
                int res = SendARP(ldest, 0, ref macinfo, ref len);
                string originalMACAddress = macinfo.ToString("X4");
                if (originalMACAddress != "0000" && originalMACAddress.Length == 12)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        macAddress.Append(originalMACAddress.Substring(10 - i * 2, 2));
                        if (i < 5)
                        {
                            macAddress.Append("-");
                        }
                    }
                }
            }
            catch (Exception)
            {
                return "No find MAC Address";
            }
    
            return macAddress.ToString();
        }
    
        /// <summary>
        /// 发送MagicPackage
        /// </summary>
        /// <param name="broadcast">广播地址</param>
        /// <param name="portNo">端口号</param>
        /// <param name="macAddress">MAC地址</param>
        /// <returns>成功时返回广播地址</returns>
        private static string SendMagicPackage(string broadcast, int portNo, string macAddress)
        {
            macAddress = macAddress.Replace(":", "").Replace("-", "");
            byte[] sendBytes = new byte[102];//总数据长度=6位同步信号+16*6位MAC地址
    
            for (int i = 0; i < 6; i++)
            {
                sendBytes[i] = 0xFF;
            }
            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    sendBytes[(i + 1) * 6 + j] = byte.Parse(macAddress.Substring(j * 2, 2), System.Globalization.NumberStyles.HexNumber);
                }
            }
    
            UdpClient udpClient = new UdpClient();
            int b = 0;
            try
            {
                b = udpClient.Send(sendBytes, sendBytes.Length, broadcast, portNo);
            }
            catch (Exception)
            {
                return "Send error";
            }
            finally
            {
                udpClient.Close();
            }
            if (102 == b)
                return broadcast;
            else
                return "Send error";
        }
    
        /// <summary>
        /// 获得广播地址
        /// </summary>
        /// <param name="ipAddress">IP地址</param>
        /// <param name="subnetMask">子网掩码</param>
        /// <param name="nt">网络类型</param>
        /// <returns>广播地址</returns>
        public static string GetBroadcast(IPAddress ipAddress, IPAddress subnetMask, NetType nt)
        {
            if (nt == NetType.Internet)
            {
                byte[] ip = ipAddress.GetAddressBytes();
                byte[] sub = subnetMask.GetAddressBytes();
    
                for (int i = 0; i < ip.Length; i++)
                {
                    ip[i] = (byte)((~sub[i]) | ip[i]);//广播地址=子网按位求反 或 IP地址
                }
    
                return new IPAddress(ip).ToString();
            }
            else
            {
                return "255.255.255.255";
            }
        }
    }
    
    

  • 相关阅读:
    SQLServer 高可用、高性能和高保护延伸
    SQLServer 通过DMV实现低影响的自动监控和历史场景追溯
    查找表包含的页和页所在的表
    出身在二三线城市软件工作者的悲哀
    SQL语句实现取消自增列属性
    基于Apache(without ssl)的svn环境搭建
    sqlite3 命令行操作
    HTML常用特殊符号集
    IOS项目目录结构和开发流程
    Mac OSX 快捷键&命令行
  • 原文地址:https://www.cnblogs.com/eshizhan/p/1741162.html
Copyright © 2011-2022 走看看