当前位置:文档之家› 远程开机关机

远程开机关机

远程开机关机----从零教起作为机房管理员,要管理的计算机较多,经常面临大量计算机要开启或关闭,如果每次逐一去开启或关闭,也是一项艰巨的任务,如果能从一台计算机上远程开启或关闭本局域网内的一台或多台计算机,将是一件轻松快乐的事。

一、远程开机1.对被开启计算机的硬件要求要实现网络远程开机,对被开启的计算机而言需要电源、主板、网卡3件设备的支持。

首先电源必须是符合ATX 2.03标准的ATX电源,而且其+5V的备用电流必须在600mA以上,以便能唤醒网卡。

其次是主板和网卡都必须支持Wake-up On LAN(WOL)技术(即远程唤醒)。

可通过查看主板网卡使用说明书确认,对主板而言可直接查看BIOS设置中的“Power Management Setup”菜单中是否有“Wake on Lan”一项来确认,有则将“Wake on Lan”设置为“Enable”,开启远程唤醒功能。

另外查看BIOS设置中是否有“Wake on PCI Card”,有则说明主板可通过PCI插槽直接向网卡供电,将其设置为“Enable”;没有则需要在主板的WOL接口(3针)和网卡的WOL接口之间连一根三芯远程唤醒电缆,以便主板给网卡供电。

2.远程开机原理远程开机的实现,主要是向目标计算机发送特殊格式的数据包(包含有6个字节的“FF”和重复16遍的目标计算机的MAC地址,共102个字节的数据),目标计算机的网卡只要检测到数据包中某个片段含有这102个字节的数据,便会将该计算机唤醒,它是AMD公司开发推广的技术。

所以远程开机需要知道目标计算机的MAC地址,如果要开启的计算机只有一台,可直接在该计算机上查看MAC地址并记录下来,但是如果有多台计算机需要开启,用这种方式麻烦且容易出错,所以应考虑编程解决这个问题。

3.编程获取局域网内各计算机的MAC地址怎么获取局域网内各计算机的MAC地址呢?了解网络通信原理的人都知道,网络中两台计算机要相互通信,看似只要相互知道IP地址即可,但那只是在网络层上,在数据链路层上最终必须知道对方计算机网卡的物理地址,即MAC地址。

那么网络通信时如何知道其它计算机的MAC地址呢?靠ARP(Address Resolution Protocol)即地址解析协议,通过在局域网内广播ARP请求包,对方即会响应,告知其MAC地址,双方计算机都会将对方的MAC地址及IP地址对应保存在一张地址映射表中,以备通信使用。

所以编程时要发送一个ARP请求包来获取指定计算机的MAC地址,Windows API中已提供现成的函数SendARP,其声明如下:DWORD SendARP(IPAddr DestIP, IPAddr SrcIP,PULONG pMacAddr, PULONGPhyAddrLen );第一个参数为要获取其MAC地址的目标计算机机的IP地址,参数类型为IPAddr,其实类型就是unsigned long (用户输入的目的主机的IP地址一般是字符串类型点式IP 地址,需要将其转换成一个3 2位的无符号长整数,可用inet_addr函数完成);第二个参数为源机的IP地址;第三个参数为存放目标计算机MAC地址的指针变量;第四个参数为存放目标计算机MAC地址字节长度的指针变量。

该函数的定义在iphlpapi.h头文件中,所以要包含#include<iphlpapi.h>;该函数的实现在Iphlpapi.lib库文件中,要在项目设置的链接中加入库文件Iphlpapi.lib。

(注意:VC6.0不含这两个文件,需网上下载,而VC7.0中含有。

)关键代码如下://将用户输入的目的主机的字符串类型点式IP地址转换成一个3 2位的无符号长整数:ULONG ULDestIP=inet_addr(strIPAddr);//发送ARP请求包获得远程MAC地址:iRusult=SendARP(ULDestIP,(unsigned long)NULL,(PULONG)&ULMacAdd,&PhyAddrLen);//由于获得的MAC地址是6字节的unsigned char数值,不便阅读,所以需要将其转换为字符串:sprintf(strMacAddr,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",ULMacAdd[0],ULMacAdd[1],ULMa cAdd[2],ULMacAdd[3],ULMacAdd[4],ULMacAdd[5]);为了实现获取机房内所有机器的MAC地址,可以采取循环的办法发送ARP请求包获得所有机器的MAC地址,考虑机房内机器的IP地址一般都是连续的,所以先获取IP地址最小的那台机器的MAC地址,然后逐一增加IP地址, 循环获取其它机器的IP地址。

//注意IP地址加一前先要将ULONG类型的IP地址从网络字节顺序转换为主机字节顺序,加一后再从主机字节顺序转换为网络字节顺序。

ULDestIP=htonl(ntohl(ULDestIP)+1);为了使用户能对比观察及关机的需要,程序中还获取了远程机的机器名,并与IP地址、MAC地址一起显示在一个ListCtrl控件中。

//获取远程机器名:struct hostent *RemoteHost;RemoteHost=(struct hostent*)malloc(sizeof(struct hostent));RemoteHost=gethostbyaddr((char*)&ULDestIP,4,AF_INET);strcpy(strRemoteHostName,RemoteHost->h_name);//将3 2位的无符号长整数IP地址转换成字符串类型点式IP地址:struct in_addr sAddr;sAddr.s_addr=ULDestIP;strcpy(strIPAddr,inet_ntoa(sAddr));//将远程机的机器名、IP地址、MAC地址一起显示在一个ListCtrl控件中:int iItemNumber=m_ListHostInfo.GetItemCount();char strNumber[4];sprintf(strNumber,"%d",iItemNumber+1);m_ListHostInfo.InsertItem(iItemNumber,strNumber); //第一列显示序号m_ListHostInfo.SetItemText(iItemNumber,1,strRemoteHostName); //第二列显示机器名m_ListHostInfo.SetItemText(iItemNumber,2,strIPAddr); //第三列显示IP地址m_ListHostInfo.SetItemText(iItemNumber,3,strMacAddr); //第四列显示MAC地址为了下次开机的需要,要将ListCtrl控件中显示的机器名、IP地址、MAC地址一一对应保存在一个文件中。

远程开机前,需要将文件中的机器名、IP地址、MAC地址读出来显示在ListCtrl控件中,在程序启动后(比如在OnInitDialog函数中)就读出来显示,以便开机和关机都可以使用。

文件读写的代码比较简单,这里就不再赘述。

4.发送远程开机数据包已经知道了要开启计算机的MAC地址,接下来便可发送远程开机的数据包了,采用广播形式发送。

关键代码如下:SOCKET SocketData=socket(AF_INET, SOCK_DGRAM, 0); //创建套接字bool bOptVal=true;int iRusult=setsockopt(SocketData,SOL_SOCKET,SO_BROADCAST,(char FAR*)&bOptVal,sizeof(bOptVal));//设置发送方式为广播发送SOCKADDR_IN RecvAddr;RecvAddr.sin_family = AF_INET;RecvAddr.sin_port = htons(0);RecvAddr.sin_addr.s_addr=htonl(INADDR_BROADCAST);为了将ListCtrl控件中所选择的计算机都开启,需要获取所有选择项中的MAC地址,然后构造远程开机数据包,逐机发送。

关键代码如下:POSITIONpos=m_ListHostInfo.GetFirstSelectedItemPosition();while(pos){int nItem=m_AddrListCtrl.GetNextSelectedItem(pos);//获取选择项strMacAddr=m_ListHostInfo.GetItemText(nItem,3);//获取选择项的第四列数据MAC地址BYTE ByteMacAddr[6];//将字符串型式MAC地址转换为6个字节的数值:sscanf(strMacAddr, "%2x-%2x-%2x-%2x-%2x-%2x",&ByteMacAddr[0], &ByteMacAddr[1], &ByteMacAddr[2], &ByteMacAddr[3], &ByteMacAddr[4], &ByteMacAddr[5]);//构造远程开机数据包BYTE bDataPacket[102];memset(bDataPacket,0xFF,6);//先写入6个字节的FFfor (int i=1; i<=16; i++)//然后循环16次写入6字节的MAC地址memcpy(bDataPacket+i*6,ByteMacAddr,6);//发送远程开机数据包iRusult=sendto(SocketData,(char FAR *)bDataPacket,102,0,(SOCKADDR *)&RecvAddr,sizeof(RecvAddr));}程序运行的主界面如图1所示。

二、远程关机远程关机的方法分两种:一种需要在被控制的计算机上编写软件(适用于任何系统)、一种不需要在被控制的计算机上编写软件(只适用于Windows2000、WindowsXP以上任何系统)。

1.有被控端软件需要编写控制端软件和被控端软件,由控制端软件发送自定义的关机命令字符串,被控端软件收到相应命令后关闭本机。

通信方式有TCP、UDP两种,TCP是面向连接的,为了保证可靠的传输可采用它,UDP是无连接的,为了提高传输速度可采用它。

由于篇幅限制且UDP方式相对简单,我这里只谈TCP方式。

相关主题