遠(yuǎn)程開機(jī)關(guān)機(jī)_第1頁(yè)
遠(yuǎn)程開機(jī)關(guān)機(jī)_第2頁(yè)
遠(yuǎn)程開機(jī)關(guān)機(jī)_第3頁(yè)
遠(yuǎn)程開機(jī)關(guān)機(jī)_第4頁(yè)
遠(yuǎn)程開機(jī)關(guān)機(jī)_第5頁(yè)
已閱讀5頁(yè),還剩4頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、遠(yuǎn)程開機(jī)關(guān)機(jī)作為機(jī)房管理員,要管理的計(jì)算機(jī)較多,經(jīng)常面臨大量計(jì)算機(jī)要開啟或關(guān)閉,如果每次逐一去開啟或關(guān)閉,也是一項(xiàng)艱巨的任務(wù),如果能從一臺(tái)計(jì)算機(jī)上遠(yuǎn)程開啟或關(guān)閉本局域網(wǎng)內(nèi)的一臺(tái)或多臺(tái)計(jì)算機(jī),將是一件輕松快樂的事。一、遠(yuǎn)程開機(jī)1對(duì)被開啟計(jì)算機(jī)的硬件要求 要實(shí)現(xiàn)網(wǎng)絡(luò)遠(yuǎn)程開機(jī),對(duì)被開啟的計(jì)算機(jī)而言需要電源、主板、網(wǎng)卡3件設(shè)備的支持。首先電源必須是符合atx 2.03標(biāo)準(zhǔn)的atx電源,而且其+5v的備用電流必須在600ma以上,以便能喚醒網(wǎng)卡。其次是主板和網(wǎng)卡都必須支持wake-up on lan(wol)技術(shù)(即遠(yuǎn)程喚醒)??赏ㄟ^查看主板網(wǎng)卡使用說(shuō)明書確認(rèn),對(duì)主板而言可直接查看bios設(shè)置中的“po

2、wer management setup”菜單中是否有“wake on lan”一項(xiàng)來(lái)確認(rèn),有則將“wake on lan”設(shè)置為“enable”, 開啟遠(yuǎn)程喚醒功能。另外查看bios設(shè)置中是否有“wake on pci card”,有則說(shuō)明主板可通過pci插槽直接向網(wǎng)卡供電,將其設(shè)置為“enable”;沒有則需要在主板的wol接口(3針)和網(wǎng)卡的wol接口之間連一根三芯遠(yuǎn)程喚醒電纜,以便主板給網(wǎng)卡供電。 2遠(yuǎn)程開機(jī)原理遠(yuǎn)程開機(jī)的實(shí)現(xiàn),主要是向目標(biāo)計(jì)算機(jī)發(fā)送特殊格式的數(shù)據(jù)包(包含有6個(gè)字節(jié)的“ff”和重復(fù)16遍的目標(biāo)計(jì)算機(jī)的mac地址,共102個(gè)字節(jié)的數(shù)據(jù)),目標(biāo)計(jì)算機(jī)的網(wǎng)卡只要檢測(cè)到數(shù)據(jù)包中

3、某個(gè)片段含有這102個(gè)字節(jié)的數(shù)據(jù),便會(huì)將該計(jì)算機(jī)喚醒,它是amd公司開發(fā)推廣的技術(shù)。所以遠(yuǎn)程開機(jī)需要知道目標(biāo)計(jì)算機(jī)的mac地址,如果要開啟的計(jì)算機(jī)只有一臺(tái),可直接在該計(jì)算機(jī)上查看mac地址并記錄下來(lái),但是如果有多臺(tái)計(jì)算機(jī)需要開啟,用這種方式麻煩且容易出錯(cuò),所以應(yīng)考慮編程解決這個(gè)問題。3編程獲取局域網(wǎng)內(nèi)各計(jì)算機(jī)的mac地址怎么獲取局域網(wǎng)內(nèi)各計(jì)算機(jī)的mac地址呢?了解網(wǎng)絡(luò)通信原理的人都知道,網(wǎng)絡(luò)中兩臺(tái)計(jì)算機(jī)要相互通信,看似只要相互知道ip地址即可,但那只是在網(wǎng)絡(luò)層上,在數(shù)據(jù)鏈路層上最終必須知道對(duì)方計(jì)算機(jī)網(wǎng)卡的物理地址,即mac地址。那么網(wǎng)絡(luò)通信時(shí)如何知道其它計(jì)算機(jī)的mac地址呢?靠arp(addr

4、ess resolution protocol)即地址解析協(xié)議,通過在局域網(wǎng)內(nèi)廣播arp請(qǐng)求包,對(duì)方即會(huì)響應(yīng),告知其mac地址,雙方計(jì)算機(jī)都會(huì)將對(duì)方的mac地址及ip地址對(duì)應(yīng)保存在一張地址映射表中,以備通信使用。所以編程時(shí)要發(fā)送一個(gè)arp請(qǐng)求包來(lái)獲取指定計(jì)算機(jī)的mac地址,windows api中已提供現(xiàn)成的函數(shù)sendarp,其聲明如下:dwordsendarp(ipaddr destip, ipaddr srcip,pulong pmacaddr, pulong phyaddrlen );第一個(gè)參數(shù)為要獲取其mac地址的目標(biāo)計(jì)算機(jī)機(jī)的ip地址,參數(shù)類型為ipaddr ,其實(shí)類型就是unsi

5、gned long (用戶輸入的目的主機(jī)的ip地址一般是字符串類型點(diǎn)式ip地址,需要將其轉(zhuǎn)換成一個(gè)3 2位的無(wú)符號(hào)長(zhǎng)整數(shù),可用inet_addr函數(shù)完成);第二個(gè)參數(shù)為源機(jī)的ip地址;第三個(gè)參數(shù)為存放目標(biāo)計(jì)算機(jī)mac地址的指針變量;第四個(gè)參數(shù)為存放目標(biāo)計(jì)算機(jī)mac地址字節(jié)長(zhǎng)度的指針變量。該函數(shù)的定義在iphlpapi.h頭文件中,所以要包含#include;該函數(shù)的實(shí)現(xiàn)在iphlpapi.lib庫(kù)文件中,要在項(xiàng)目設(shè)置的鏈接中加入庫(kù)文件iphlpapi.lib。(注意:vc6.0不含這兩個(gè)文件,需網(wǎng)上下載,而vc7.0中含有。)關(guān)鍵代碼如下:/將用戶輸入的目的主機(jī)的字符串類型點(diǎn)式ip地址轉(zhuǎn)換成一

6、個(gè)3 2位的無(wú)符號(hào)長(zhǎng)整數(shù):ulong uldestip=inet_addr(stripaddr);/發(fā)送arp請(qǐng)求包獲得遠(yuǎn)程mac地址:irusult=sendarp(uldestip,(unsigned long)null,(pulong)&ulmacadd,&phyaddrlen); /由于獲得的mac地址是6字節(jié)的unsigned char數(shù)值,不便閱讀,所以需要將其轉(zhuǎn)換為字符串:sprintf(strmacaddr,%.2x-%.2x-%.2x-%.2x-%.2x-%.2x,ulmacadd0,ulmacadd1,ulmacadd2,ulmacadd3,ulmacadd4,ulmaca

7、dd5);為了實(shí)現(xiàn)獲取機(jī)房?jī)?nèi)所有機(jī)器的mac地址,可以采取循環(huán)的辦法發(fā)送arp請(qǐng)求包獲得所有機(jī)器的mac地址,考慮機(jī)房?jī)?nèi)機(jī)器的ip地址一般都是連續(xù)的,所以先獲取ip地址最小的那臺(tái)機(jī)器的mac地址,然后逐一增加ip地址, 循環(huán)獲取其它機(jī)器的ip地址。/注意ip地址加一前先要將ulong類型的ip地址從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機(jī)字節(jié)順序,加一后再?gòu)闹鳈C(jī)字節(jié)順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序。uldestip=htonl(ntohl(uldestip)+1); 為了使用戶能對(duì)比觀察及關(guān)機(jī)的需要,程序中還獲取了遠(yuǎn)程機(jī)的機(jī)器名,并與ip地址、mac地址一起顯示在一個(gè)listctrl控件中。/獲取遠(yuǎn)程機(jī)器名:struct

8、 hostent *remotehost; remotehost=(struct hostent*)malloc(sizeof(struct hostent);remotehost=gethostbyaddr(char*)&uldestip,4,af_inet); strcpy(strremotehostname,remotehost-h_name); /將3 2位的無(wú)符號(hào)長(zhǎng)整數(shù)ip地址轉(zhuǎn)換成字符串類型點(diǎn)式ip地址:struct in_addr saddr; saddr.s_addr=uldestip; strcpy(stripaddr,inet_ntoa(saddr);/將遠(yuǎn)程機(jī)的機(jī)器名、i

9、p地址、mac地址一起顯示在一個(gè)listctrl控件中:int iitemnumber=m_listhostinfo.getitemcount();char strnumber4;sprintf(strnumber,%d,iitemnumber+1);m_listhostinfo.insertitem(iitemnumber,strnumber); /第一列顯示序號(hào)m_listhostinfo.setitemtext(iitemnumber,1,strremotehostname); /第二列顯示機(jī)器名m_listhostinfo.setitemtext(iitemnumber,2,strip

10、addr); /第三列顯示ip地址m_listhostinfo.setitemtext(iitemnumber,3,strmacaddr); /第四列顯示mac地址為了下次開機(jī)的需要,要將listctrl控件中顯示的機(jī)器名、ip地址、mac地址一一對(duì)應(yīng)保存在一個(gè)文件中。遠(yuǎn)程開機(jī)前,需要將文件中的機(jī)器名、ip地址、mac地址讀出來(lái)顯示在listctrl控件中,在程序啟動(dòng)后(比如在oninitdialog函數(shù)中)就讀出來(lái)顯示,以便開機(jī)和關(guān)機(jī)都可以使用。文件讀寫的代碼比較簡(jiǎn)單,這里就不再贅述。4.發(fā)送遠(yuǎn)程開機(jī)數(shù)據(jù)包已經(jīng)知道了要開啟計(jì)算機(jī)的mac地址,接下來(lái)便可發(fā)送遠(yuǎn)程開機(jī)的數(shù)據(jù)包了,采用廣播形式發(fā)送

11、。關(guān)鍵代碼如下:socket socketdata=socket(af_inet, sock_dgram, 0); /創(chuàng)建套接字bool boptval=true;int irusult=setsockopt(socketdata,sol_socket,so_broadcast,(char far *)&boptval,sizeof(boptval);/設(shè)置發(fā)送方式為廣播發(fā)送sockaddr_in recvaddr;recvaddr.sin_family = af_inet; recvaddr.sin_port = htons(0);recvaddr.sin_addr.s_addr=htonl

12、(inaddr_broadcast);為了將listctrl控件中所選擇的計(jì)算機(jī)都開啟,需要獲取所有選擇項(xiàng)中的mac地址,然后構(gòu)造遠(yuǎn)程開機(jī)數(shù)據(jù)包,逐機(jī)發(fā)送。關(guān)鍵代碼如下:position pos=m_listhostinfo.getfirstselecteditemposition(); while(pos) int nitem=m_addrlistctrl.getnextselecteditem(pos);/獲取選擇項(xiàng) strmacaddr=m_listhostinfo.getitemtext(nitem,3);/獲取選擇項(xiàng)的第四列數(shù)據(jù)mac地址byte bytemacaddr6; /將字符

13、串型式mac地址轉(zhuǎn)換為6個(gè)字節(jié)的數(shù)值:sscanf(strmacaddr, %2x-%2x-%2x-%2x-%2x-%2x,&bytemacaddr0, &bytemacaddr1, &bytemacaddr2, &bytemacaddr3, &bytemacaddr4, &bytemacaddr5);/構(gòu)造遠(yuǎn)程開機(jī)數(shù)據(jù)包byte bdatapacket102;memset(bdatapacket,0xff,6);/先寫入6個(gè)字節(jié)的fffor (int i=1; igetmainwnd();while(1)sockaccept=accept(powerdlg-m_socklisten,(soc

14、kaddr*)&clientaddr,&iaddrlen);ulclientipaddr=clientaddr.sin_addr.s_addr;for(int i=0;im_listhostinfo.getitemcount();i+)stripaddr=powerdlg-m_listhostinfo.getitemtext(i,2);if(ulclientipaddr=inet_addr(stripaddr)powerdlg-m_sockclienti=sockaccept;/為了知道哪些客戶機(jī)已建立了連接,我順便在listctrll控件中對(duì)應(yīng)連接客戶機(jī)那一行的第五列打作為標(biāo)記:powerd

15、lg-m_listhostinfo.setitemtext(i,4,);break;最后在用戶點(diǎn)擊關(guān)機(jī)按鈕或菜單時(shí)發(fā)送自定義的關(guān)機(jī)命令字符串:position pos=m_listhostinfo.getfirstselecteditemposition(); while(pos) int nitem=m_listhostinfo.getnextselecteditem(pos);/獲取選擇項(xiàng) send(m_sockclientnitem,powoff,com_str_len,0);closesocket(m_sockclientnitem);/關(guān)閉套接字m_listhostinfo.seti

16、temtext(nitem,4,); (2)客戶端先解析服務(wù)器名,然后用s o c k e t創(chuàng)建一個(gè)套接字,再用c o n n e c t創(chuàng)建與服務(wù)器的連接。最后等待接收關(guān)機(jī)命令字符串:cstring strserveripaddr=;/此處為服務(wù)端的ip地址socket sockclient;sockaddr_in serversockaddr;serversockaddr.sin_addr.s_addr=inet_addr(strserveripaddr);serversockaddr.sin_family=af_inet;serversockaddr.sin_po

17、rt=htons(server_port);sockclient=socket(af_inet,sock_stream,0);while(connect(sockclient,(sockaddr*)&serversockaddr,sizeof(serversockaddr)!=0);int iallrecvlen=0,ithisrecvlen=0;char strrecvbufcom_str_len+1=;while(ithisrecvlen!=socket_error&iallrecvlencom_str_len)/循環(huán)接收數(shù)據(jù)ithisrecvlen=recv(sockclient,str

18、recvbuf+iallrecvlen,com_str_len,0);iallrecvlen+=ithisrecvlen;被控端收到命令字符串后,調(diào)用exitwindowsex函數(shù)關(guān)閉或重啟本客戶機(jī)。exitwindowsex函數(shù)在windows9x系統(tǒng)中可直接使用,在windows2000或windows以上系統(tǒng)中默認(rèn)的情況下進(jìn)程不具有關(guān)機(jī)權(quán)限,所以要將當(dāng)前進(jìn)程的關(guān)機(jī)權(quán)限enabled。先通過openprocesstoken函數(shù)獲得當(dāng)前進(jìn)程訪問令牌的句柄,該函數(shù)聲明如下:boolopenprocesstoken (handle processhandle,dword desiredacces

19、s,phandle tokenhandle);第一參數(shù)是要修改權(quán)限的進(jìn)程句柄;第二個(gè)參數(shù)為對(duì)該令牌的訪問類型;第三個(gè)參數(shù)即獲得的進(jìn)程訪問令牌的句柄。為了修改進(jìn)程令牌權(quán)限,還要先定義一個(gè)令牌權(quán)限token_privileges類型結(jié)構(gòu)變量,該結(jié)構(gòu)定義如下:typedef struct _token_privileges dword privilegecount; luid_and_attributes privilegesanysize_array; token_privileges第一個(gè)成員變量為權(quán)限數(shù)量;第二個(gè)成員變量為luid_and_attributes類型結(jié)構(gòu)變量數(shù)組。該結(jié)構(gòu)定義如下:

20、typedef struct _luid_and_attributes luid luid; dword attributes; luid_and_attributes;第一個(gè)成員變量為某權(quán)限的本地唯一標(biāo)識(shí);第二個(gè)成員變量為該權(quán)限屬性。為了獲取某權(quán)限的本地唯一標(biāo)識(shí),需要通過lookupprivilegevalue函數(shù),該函數(shù)聲明如下:boollookupprivilegevaluea(lpcstr lpsystemname,lpcstr lpname,pluid lpluid);第一個(gè)參數(shù)為系統(tǒng)名,本地系統(tǒng)為nul;第二個(gè)參數(shù)為權(quán)限名;第三個(gè)參數(shù)為返回的權(quán)限本地唯一標(biāo)識(shí)。定義好了令牌權(quán)限tok

21、en_privileges結(jié)構(gòu)變量后,最后通過adjusttokenprivileges函數(shù)修改訪問令牌權(quán)限,該函數(shù)聲明如下:booladjusttokenprivileges (handle tokenhandle,bool disableallprivileges, ptoken_privileges newstate,dword bufferlength,ptoken_privilegesreviousstate, pdword returnlength);第一個(gè)參數(shù)為訪問令牌句柄;第二個(gè)參數(shù)為是否取消所有權(quán)限;第三個(gè)參數(shù)為前面定義好的令牌權(quán)限;后面三個(gè)參數(shù)針用于保存修改前的令牌權(quán)限,分

22、別為用于保存的內(nèi)存長(zhǎng)度、保存的內(nèi)存地址、實(shí)際保存的內(nèi)存長(zhǎng)度。具體代碼如下:if(strcmp(powoff,strrecvbuf)=0)closesocket(sockclient);wsacleanup();if(getversion()0x80000000)/判斷windows系統(tǒng)版本號(hào)handle hprocesstoken;token_privileges tkp;openprocesstoken(getcurrentprocess(),token_adjust_privileges|token_query,&hprocesstoken);lookupprivilegevalue(nu

23、ll,se_shutdown_name,&tkp.privileges0.luid);tkp.privilegecount = 1; tkp.privileges0.attributes = se_privilege_enabled;adjusttokenprivileges(hprocesstoken,false,&tkp,0,(ptoken_privileges)null,0);/強(qiáng)迫所有進(jìn)程退出、關(guān)閉計(jì)算機(jī)并切斷電源exitwindowsex(ewx_force|ewx_poweroff,0); 在windows2000或windows以上系統(tǒng)中,也可用initiatesystemshu

24、tdown函數(shù)代替exitwindowsex函數(shù)關(guān)閉本機(jī),initiatesystemshutdown函數(shù)的使用在下面介紹。2無(wú)被控端軟件由于windows2000、windowsxp以上的系統(tǒng)本身支持遠(yuǎn)程關(guān)機(jī),所以也可不編寫被控端軟件,windows api中已提供現(xiàn)成的函數(shù)initiatesystemshutdown,其聲明如下:boolinitiatesystemshutdowna(lpstr lpmachinename,lpstr lpmessage,dword dwtimeout,bool bforceappsclosed,bool brebootaftershutdown);第一個(gè)

25、參數(shù)為機(jī)器名,本機(jī)為null;第二個(gè)參數(shù)為關(guān)機(jī)提示對(duì)話框中顯示的消息;第三個(gè)參數(shù)為關(guān)機(jī)前提示的時(shí)間;第四個(gè)參數(shù)為是否強(qiáng)制關(guān)閉應(yīng)用程序;第五個(gè)參數(shù)為是否重啟。遠(yuǎn)程關(guān)機(jī)需要具有相應(yīng)權(quán)限,如果在域環(huán)境下可以直接以域管理員身份登錄系統(tǒng)獲得遠(yuǎn)程關(guān)機(jī)的權(quán)限,一般在機(jī)房或網(wǎng)吧中都是工作組環(huán)境,無(wú)法直接獲得遠(yuǎn)程關(guān)機(jī)的權(quán)限,怎么辦呢?通過試驗(yàn)我找到了一個(gè)辦法,具體步驟如下:(1)在被控機(jī)上通過“計(jì)算機(jī)管理”建立一個(gè)用戶,然后在“組策略”中給該用戶配置遠(yuǎn)程關(guān)機(jī)權(quán)限,具體操作為:運(yùn)行“gpedit.msc”打開“組策略編輯器”。在“組策略”左側(cè)樹窗口中依次打開“計(jì)算機(jī)配置”、“windows 設(shè)置”、“安全設(shè)置”、

26、“本地策略”、“用戶權(quán)利指派”。在“組策略”右側(cè)列表窗口選擇“從遠(yuǎn)端系統(tǒng)強(qiáng)制關(guān)機(jī)”策略添加該用戶。(2)在工作組環(huán)境中無(wú)法直接以該用戶賬號(hào)從控制機(jī)登錄被控機(jī),需要在控制機(jī)上創(chuàng)建與被控機(jī)上一致的用戶賬號(hào)(用戶名和密碼都需相同),可預(yù)先通過“計(jì)算機(jī)管理”完成,也可在調(diào)用關(guān)機(jī)代碼前臨時(shí)通過下面的代碼來(lái)創(chuàng)建:net_api_status retstatus = 0;dword dwerror = 0; user_info_1 structuserinfo;zeromemory(&structuserinfo, sizeof(structuserinfo);structuserinfo.usri1_name = szusername;structuserinfo.usri1_password= szpassword;structuserinfo.usri1_priv = user_priv_user;structuserinfo.usri1_flags = uf_normal_account;retstatus = netuseradd(null, 1, (lpbyte)(&structuserinfo), &d

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論