wake on lan是一種網路喚醒功能,它可以實現遠程開機,剛好實驗室有一台ftp伺服器,因為不是24小時開機的,所以每次開機都要跑過去用手按開關,非常麻煩,於是在網上找了下資料,自己實現了一把,並在windows下用Qt寫了個簡單的介面,以後想開伺服器就方便了。原理就是源主機廣播一個特殊的資料包給目的主機,前提是目的主機的主板支援wake on lan並在BIOS裡已經設定好,還有就是要知道目的主機的MAC地址。這個特殊的資料包叫做magic packet,它由102個位元組組成,最前面六個位元組為0xFF,其他位元組為目的主機的MAC地址(6個位元組為一組,共16組),如所示:
知道這個原理之後就可以很容易實現了,實現代碼如下,本人親測。
1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include <sys/ioctl.h> 4 #include <net/if.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <stdlib.h> 8 9 10 int main(int argc, char* argv[])11 {12 unsigned char mac[6]={0x00,0x10,0x20,0x30,0x40,0x50};//目的主機MAC地址,例如: 00:10:20:30:40:5013 unsigned char packet[102];14 struct sockaddr_in addr;15 int sockfd, i,j, on = 1;16 17 //構建magic packet18 for(i=0;i<6;i++) 19 packet[i] = 0xFF; 20 21 for(i=1;i<17;i++)22 for(j=0;j<6;j++)23 packet[i*6+j] = mac[j];24 25 //UDP26 sockfd = socket(AF_INET, SOCK_DGRAM, 0);27 //廣播28 setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));29 if(sockfd < 0)30 exit(0);31 32 memset((void*)&addr, 0, sizeof(addr));33 addr.sin_family = AF_INET;34 addr.sin_port = htons(10000);35 addr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");//廣播位址36 37 sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&addr, sizeof(addr));38 close(sockfd);39 40 return 0;41 }
實際中需要根據目的主機來修改MAC地址和廣播位址。