Wake-on-LAN(远端唤醒) 原理及实现
Wake-on-LAN简称WOL或WoL,我们一般将其称为“网络唤醒”、“远端唤醒”技术。WOL是一种技术,同时也是该技术的规范标准,它的功效在于让已经进入休眠状态或关机状态的电脑,透过局域网(多半为以太网)的另一端对其发令,使其从休眠状态唤醒、恢复成运作状态,或从关机状态转成开机状态。此外,与WOL相关的技术也包括远端下令关机、远端下令重新开机等相关的遥控机制。
Wake-on-LAN功能需要有主板和网卡的支持,在主板BIOS中的网卡设置中必须有“Wake On LAN”设置(开启:On),并且相应网卡也得支持该功能。因为,在关闭计算机以后,其实网卡仍然通电的(unless 你把插排电源也关了),这样你就可以通过发送一段Magic Packet给网卡,让网卡将计算机唤醒。
Magic Packet
Magic Packet是一个广播帧(frame),透过端口7或端口9进行发送,且可以用无连接(Connectionless protocol)的通讯协议(如UDP、IPX)来传递,不过一般而言多是用UDP,原因是Novell公司的Netware网络操作系统的IPX协定已经很少使用。
在Magic Packet内,每次都会先有连续6个"FF"(十六进制,换算成二进制即:11111111)的资料,即:FF FF FF FF FF FF,在连续6个"FF"后则开始带出MAC地址,有时还会带出4字节或6字节的密码,一旦经由网卡侦测、解读、研判(广播)Magic Packet的内容,内容中的MAC地址、密码若与电脑自身的地址、密码吻合,就会启动唤醒、开机的程序。
示例:
假设你的网卡物理地址为00:15:17:53:d4:f9, 这段Magic Packet内容如下:
FFFFFFFFFFFF00151753d4f900151753d4f900151753d4f900151753d4f9
00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9
00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9
00151753d4f900151753d4f9
以下是根据wakelan代码修改的工具,添加了绑定网卡的支持(参数 -i devname).
/* * * Copyright (C) 1998 by Christopher Chan-Nui * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #define HAVE_GETOPT_H #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> #ifdef HAVE_GETOPT_H #include <getopt.h> #endif #include <errno.h> #include <net/if.h> //#include <linux/if.h> #ifndef DEFAULTMAC #define DEFAULTMAC "00a0c9852a5f" #endif #ifndef DEFAULTTARGET #define DEFAULTTARGET "255.255.255.255" #endif static char *rcsid="@(#) $Id: wakelan.c,v 1.8 1998/08/30 05:04:28 channui Exp $"; static void *use_rcsid = ( void * )( ( char * )&use_rcsid || ( void * )&rcsid ); char *versionid = "1.0"; void usage( char *name ) { printf ( "Usage: %s [options] [mac] [broadcast] [port]/n" " -b addr broadcast address/n" " -m mac mac address of host/n" " -p port UDP port to broadcast to/n" " -i dev bind socket to net device/n" " -v[v] version/n" , name ); exit ( 0 ); } int parse_mac( unsigned char *mac, char *str ) { int i; int count; char c; unsigned char val; int colon_ok = 1; for ( i = 0; i < 6; i++ ) { mac[i] = 0; } for ( i = 0; i < 6; i++ ) { count = 0; val = 0; do { c = toupper( *str++ ); if ( c >= '0' && c <= '9' ) { val = ( val * 16 ) + ( c - '0' ); } else if ( c >= 'A' && c <= 'F' ) { val = ( val * 16 ) + ( c - 'A' ) + 10; } else if ( c == ':' ) { if ( colon_ok || count-- != 0 ) break; } else if ( c == '/0' ) { str--; break; } else { return 0; } colon_ok=1; } while ( ++count < 2 ); colon_ok=( count<2 ); *mac++ = val; } if ( *str ) return 0; return 1; } int main ( int argc, char *argv[] ) { int sock; int optval = 1; int version =0; int i, j, c, rc; char msg[1024]; int msglen = 0; struct sockaddr_in bcast; struct hostent *he; struct in_addr inaddr; unsigned char macaddr[6]; char *mac = DEFAULTMAC; char *target = DEFAULTTARGET; short bport = htons( 32767 ); struct ifreq if_bind; char *devname = NULL; while ( ( c = getopt( argc, argv, "hvp:m:b:i:" ) ) != EOF ) { switch ( c ) { case 'b': target = optarg; break; case 'm': mac = optarg; break; case 'p': bport = htons( atoi( optarg ) ); break; case 'v': version++; break; case 'i': devname = optarg; break; case 'h': case '?': usage( argv[0] ); } } if ( version ) { printf ( "Version: %s/n", versionid ); if ( version > 1 ) { printf ( " RCSID: %s/n", rcsid ); } exit ( 0 ); } if ( argv[optind] != NULL ) { mac = argv[optind++]; } if ( argv[optind] != NULL ) { target = argv[optind++]; } if ( argv[optind] != NULL ) { bport = htons( atoi( argv[optind++] ) ); } if ( argv[optind] != NULL ) { usage( argv[0] ); } if ( !parse_mac( macaddr, mac ) ) { printf ( "Illegal MAC address '%s'/n", mac ); exit ( 1 ); } if ( !inet_aton( target, &inaddr ) ) { he = gethostbyname( target ); inaddr = *( struct in_addr * )he->h_addr_list[0]; } for ( i = 0; i < 6; i++ ) { msg[msglen++] = 0xff; } for ( i = 0; i < 16; i++ ) { for ( j = 0; j < sizeof( macaddr ); j++ ) { msg[msglen++] = macaddr[j]; } } memset( &bcast, 0, sizeof( bcast ) ); bcast.sin_family = AF_INET; bcast.sin_addr.s_addr = inaddr.s_addr; bcast.sin_port = bport; sock = socket( AF_INET, SOCK_DGRAM, 0 ); if ( sock < 0 ) { printf ( "Can't allocate socket/n" ); exit ( 1 ); } rc = setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof( optval ) ); if ( rc < 0 ) { printf ( "Can't socket option SO_BROADCAST: rc = %d, errno=%s(%d)/n", rc, strerror( errno ), errno ); exit ( 1 ); } if ( NULL != devname ) { memset( &if_bind, 0x0, sizeof( if_bind ) ); strncpy( if_bind.ifr_name, devname, IFNAMSIZ ); rc = setsockopt( sock, SOL_SOCKET, SO_BINDTODEVICE, &if_bind, sizeof( if_bind ) ); if ( rc < 0 ) { printf( "Can't socket option SO_BINDTODEVICE: rc = %d, errno=%s(%d)/n", rc, strerror( errno ), errno ); exit( 1 ); } } sendto( sock, &msg, msglen, 0, ( struct sockaddr * )&bcast, sizeof( bcast ) ); close( sock ); return 0; }
参考:
Wake on LAN mini HOWTO http://gsd.di.uminho.pt/jpo/software/wakeonlan/mini-howto/
Wake-on-LAN http://en.wikipedia.org/wiki/Wake-on-LAN
wakelan Author: Christopher Chan-Nui ftp://metalab.unc.edu/pub/Linux/system/network/misc/wakelan-1.1.tar.gz
Wake-on-LAN(远端唤醒) 原理及实现相关推荐
- WOL(Wake On LAN - 局域网唤醒)外网唤醒 配置教程 远程开机
虽然这个功能叫局域网唤醒,但与路由器的端口映射功能配合,广域网唤醒也是很容易的.只要有一台能上网的电脑或手机,就能把家中电脑打开,需要用家里电脑又不在家的时候很方便. 注意事项: 此教程是为了实现外网 ...
- WOL 实现命令。(Wake On LAN - 局域网唤醒)
1 wakeonlan 00:11:22:33:44:55 2 正确的做法是,如果用wol,则需要指定向电脑所在的网段广播: /usr/bin/wol -i 192.168.1.255 40:8D:5 ...
- 在Linux下通过Wake On LAN实现网络唤醒远程开机
我们经常有这样的场景或需求,人在外面,需要将家里的机器或公司的机器开启,进行远程控制操作. 有几种方式可以实现远程开机,一是通过主板的来电自启动,通过智能开关远程开机.还有一种方式就是可以通过一台已经 ...
- wake on lan 远程唤醒/远程开机中的所有设置细节(arp静态绑定解决长时间关机无法唤醒)
远程开机这个功能实在屌爆了,工作中会经常遇到需要远程开机的情景,比如说,晚上在家里,突然接到领导的电话需要改东西,然而家里的电脑又没有工作环境,各种工具软件都没有安装,这时如果往公司跑一趟真是麻烦,或 ...
- PHP实现局域网或者广域网唤醒笔记本电脑wake on lan/wan
网上有很多APP或者EXE形式的wake on lan软件,好用,但是得下载安装个软件. 通过PHP网页版的方式则不需要安装任何软件,只要可以上网打开网页即可实现远程唤醒. 第一步:设置电脑网卡的唤醒 ...
- python控制电脑唤醒键_大神教你用Python实现Wake On Lan远程开机功能
导读 这篇文章主要介绍了使用Python实现Wake On Lan远程开机功能,文中给大家补充介绍了python通过wakeonlan唤醒内网电脑开机,非常不错,感兴趣的朋友跟随小编一起学习吧 Wak ...
- 基于OpenWrt的Wol(wake on lan)远程唤醒
原理:向支持唤醒的网卡,发送特定格式的数据帧,从而启动计算机.正想起名字Wol,wake on lan 一样,是通过lan口发送的数据.所以设备要通过网线和路由器相连. 功能比较好实现,只有两个点: ...
- WOL wake on lan 功能 nodejs android kotlin实现
有些机器支持WOL功能,可以远程唤醒机器, 几乎所有品牌的硬件都支持WOL,由于安全原因,可能在软件上默认WOL处于关闭状态 原理 WOL(Wake on Lan),即局域网唤醒,从根本上来说是硬件设 ...
- 总结几点 Wake On Lan (WOL) 失败的原因
正文 在我想使用 Wake On Lan(后文皆用 WOL 代替)这项技术远程开机时,总是失败,在查阅各种资料后成功使用上了 WOL,下面总结几点导致失败的原因. 1,发送 Magic Packet( ...
最新文章
- Linux下独立添加PHP扩展模块 mssql
- 产品研究分析--王者荣耀的那些套路
- 测试手机信号格数软件,超详细教程之教你如何查询手机信号的强度
- 在mysql中删除表正确的是什么_在MySQL中删除表的操作教程
- 全局变量-global关键字修改全局变量
- python 进程池不足_python 进程池pool简单使用
- HashMap与ConcurrentHashMap的底层原理
- LINUX修改文件权限
- JAVA微信公众号(三) 群发消息
- Java毕设项目-社区居民健康档案管理系统
- 图片免费压缩——在线压缩JPG方法分享
- android7.0版本适配(一):应用间文件文件共享——FileProvider
- 机器学习中的评估指标与损失函数
- 夺命雷公狗---DEDECMS----21dedecms按照地区取出电影内容
- 环保在线监测系统,网页版,提供源码
- java实现deflate文件格式解压压缩
- 计算机等级考试湖北准考证查询,2016年9月湖北计算机一级准考证打印入口及网址,计算机等级考试时间查询...
- 制作网页过程中,经常用到的代码
- 用等价类和边界值法设计NextDate问题的测试用例并进行测试,具体要求如下:NextDate是一个有3个变量(月份、日期和年)的函数。函数返回输入日期后一天的日期。变量月份、日期和年都具有整数值
- 通过c++ 实现dfs算法
热门文章
- iPhone备忘录清除缓存
- 计算机毕业设计(63)php小程序毕设作品之校园新生报到小程序系统
- JavaWeb+MySql+Tomcat一键部署方案
- 自动化立体仓库使用流程!海格里斯自动化立体库流程:入库——出库——拣选
- 如何阅读Smalltalk程序
- python 几何教学_GEE学习笔记 八十三:【GEE之Python版教程十三】几何图形
- 怎么把图片转换成BMP格式
- 【Educoder作业】绘制炸弹轨迹 I——绘制一个坐标点
- Github建立远程库,并从本地导入
- 数据结构与算法笔记:抽象思维之转换视角,提炼共性(分书和八皇后问题算法重构)