遠程開機關機_第1頁
遠程開機關機_第2頁
遠程開機關機_第3頁
遠程開機關機_第4頁
遠程開機關機_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

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

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

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

7、dd5);為了實現(xiàn)獲取機房內所有機器的mac地址,可以采取循環(huán)的辦法發(fā)送arp請求包獲得所有機器的mac地址,考慮機房內機器的ip地址一般都是連續(xù)的,所以先獲取ip地址最小的那臺機器的mac地址,然后逐一增加ip地址, 循環(huán)獲取其它機器的ip地址。/注意ip地址加一前先要將ulong類型的ip地址從網絡字節(jié)順序轉換為主機字節(jié)順序,加一后再從主機字節(jié)順序轉換為網絡字節(jié)順序。uldestip=htonl(ntohl(uldestip)+1); 為了使用戶能對比觀察及關機的需要,程序中還獲取了遠程機的機器名,并與ip地址、mac地址一起顯示在一個listctrl控件中。/獲取遠程機器名: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位的無符號長整數(shù)ip地址轉換成字符串類型點式ip地址:struct in_addr saddr; saddr.s_addr=uldestip; strcpy(stripaddr,inet_ntoa(saddr);/將遠程機的機器名、i

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

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

11、。關鍵代碼如下: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);/設置發(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控件中所選擇的計算機都開啟,需要獲取所有選擇項中的mac地址,然后構造遠程開機數(shù)據(jù)包,逐機發(fā)送。關鍵代碼如下:position pos=m_listhostinfo.getfirstselecteditemposition(); while(pos) int nitem=m_addrlistctrl.getnextselecteditem(pos);/獲取選擇項 strmacaddr=m_listhostinfo.getitemtext(nitem,3);/獲取選擇項的第四列數(shù)據(jù)mac地址byte bytemacaddr6; /將字符

13、串型式mac地址轉換為6個字節(jié)的數(shù)值:sscanf(strmacaddr, %2x-%2x-%2x-%2x-%2x-%2x,&bytemacaddr0, &bytemacaddr1, &bytemacaddr2, &bytemacaddr3, &bytemacaddr4, &bytemacaddr5);/構造遠程開機數(shù)據(jù)包byte bdatapacket102;memset(bdatapacket,0xff,6);/先寫入6個字節(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;/為了知道哪些客戶機已建立了連接,我順便在listctrll控件中對應連接客戶機那一行的第五列打作為標記:powerd

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

16、temtext(nitem,4,); (2)客戶端先解析服務器名,然后用s o c k e t創(chuàng)建一個套接字,再用c o n n e c t創(chuàng)建與服務器的連接。最后等待接收關機命令字符串:cstring strserveripaddr=;/此處為服務端的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;被控端收到命令字符串后,調用exitwindowsex函數(shù)關閉或重啟本客戶機。exitwindowsex函數(shù)在windows9x系統(tǒng)中可直接使用,在windows2000或windows以上系統(tǒng)中默認的情況下進程不具有關機權限,所以要將當前進程的關機權限enabled。先通過openprocesstoken函數(shù)獲得當前進程訪問令牌的句柄,該函數(shù)聲明如下:boolopenprocesstoken (handle processhandle,dword desiredacces

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

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

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

22、別為用于保存的內存長度、保存的內存地址、實際保存的內存長度。具體代碼如下:if(strcmp(powoff,strrecvbuf)=0)closesocket(sockclient);wsacleanup();if(getversion()0x80000000)/判斷windows系統(tǒng)版本號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);/強迫所有進程退出、關閉計算機并切斷電源exitwindowsex(ewx_force|ewx_poweroff,0); 在windows2000或windows以上系統(tǒng)中,也可用initiatesystemshu

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

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

26、“本地策略”、“用戶權利指派”。在“組策略”右側列表窗口選擇“從遠端系統(tǒng)強制關機”策略添加該用戶。(2)在工作組環(huán)境中無法直接以該用戶賬號從控制機登錄被控機,需要在控制機上創(chuàng)建與被控機上一致的用戶賬號(用戶名和密碼都需相同),可預先通過“計算機管理”完成,也可在調用關機代碼前臨時通過下面的代碼來創(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論