wake on lan是一种网络唤醒功能,它可以实现远程开机,刚好实验室有一台ftp服务器,因为不是24小时开机的,所以每次开机都要跑过去用手按开关,非常麻烦,于是在网上找了下资料,自己实现了一把,并在windows下用Qt写了个简单的界面,以后想开服务器就方便了。原理就是源主机广播一个特殊的数据包给目的主机,前提是目的主机的主板支持wake on lan并在BIOS里已经设置好,还有就是要知道目的主机的MAC地址。这个特殊的数据包叫做magic packet,它由102个字节组成,最前面六个字节为0xFF,其他字节为目的主机的MAC地址(6个字节为一组,共16组)
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if (argc!=3||argc!=5) {
printf("\nUsage: %s -mac 00:10:20:30:40:50 -adr 192.168.1.255\n",argv[0]);
}
unsigned char mac[6]={0x00,0x10,0x20,0x30,0x40,0x50};//目的主机MAC地址,例如: 00:10:20:30:40:50
char adr[17]="";
unsigned char packet[102];
struct sockaddr_in addr;
int sockfd, i,j, on = 1;
for (int i=0 ;i<argc;i++){
if (!strcmp(argv[i],"-mac")){
sscanf(argv[i+1], "%02x:%02x:%02x:%02x:%02x:%02x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
printf("Mac is %s,mac is %02x%02x%02x%02x%02x%02x\n",argv[i+1],mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
}
if (!strcmp(argv[i],"-adr")){
strcpy(adr,argv[i+1]);
printf("广播地址 is %s\n",adr);
}
}
//构建magic packet
for(i=0;i<6;i++)
packet[i] = 0xFF;
for(i=1;i<17;i++)
for(j=0;j<6;j++)
packet[i*6+j] = mac[j];
//UDP
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//广播
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));
if(sockfd < 0)
exit(0);
memset((void*)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(10000);
addr.sin_addr.s_addr = inet_addr(adr);//广播地址
sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&addr, sizeof(addr));
close(sockfd);
return 0;
}