1. 在BIOS设置支持网络唤醒

大多数集成网卡都能实现网络唤醒功能,不过需要事先进入BIOS中开启网络唤醒功能,不同主板的设置不一样,以VIA 主板为例,在BIOS中找到“OnBoard LAN”选项,将它设成“Enabled”。同时将“POWER MANAGEMENT SETUP(电源管理设置)”下的“Power On by LAN/Ring”选项设为“Enabled”,最后将“Wake On LAN(网络唤醒)”选项设置为“Enabled”,设置好后保存退出。

不同系统可能还需要额外的操作才能保证网络唤醒的可用性,以win10系统为例:

打开设备管理器,进入网络适配器中自己网卡的属性设置,把相关的服务都启用了。

2. 网络唤醒的必备条件

  • 网络唤醒需要终端的主板和网卡支持,需要先在BIOS设置支持网络唤醒
  • 网络唤醒要接通电源保证网卡能通电 要接网线 不能是wifi
  • 如果强制关机 可能不能通过网络唤醒来开机
  • 跨交换机或者跨路由的话就有可能不支持唤醒
  • 跨多层交换机的话即使ping通也未必能唤醒
  • 在同一网段下进行网络唤醒最为省事

3. 网络唤醒原理

这里提到一个魔术包Magic Packet的概念,魔术包指AMD公司开发的唤醒数据包,其实是一种特定的数据格式。将唤醒魔术包发送的被唤醒机器的网卡上,具有远程唤醒的网卡都支持这个标准,用16进制表示。

假设你的网卡物理地址为00:15:17:53:d4:f9, 这段Magic Packet内容如下:

FFFFFFFFFFFF00151753d4f900151753d4f900151753d4f900151753d4f9
    00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9
    00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9
    00151753d4f900151753d4f9

这段数据转化为二进制的数据,通过socket技术发送数据包以及目的mac和目的广播地址,就会唤醒目的网卡,从而唤醒主机。

数据包流向图:

当数据包被广播到192.168.1网段之后,根据数据携带的mac信息匹配到具体的主机。

4. 广播地址

这里主要讲解广播地址的概念和计算。

所谓广播地址指同时向网上所有的主机发送报文。

对一个既定的ip来说,其网络地址就是主机位全换成0,广播地址就是主机位是全换成1

例子:先把子网掩码化成二进制,再对应的把子网掩码后面是0的部分对着Ip地址换成0和1就是网络地址和主机地址,比如

192.168.1.3 (地址)/255.255.255.252(掩码) ,换算一下成二进制

11111111.11111111.11111111.111111 00 /掩码

11000000.10101000.00000001.000000 11 /地址

掩码后两位是0,那么把地址的后两位换成0就是网络地址,换成1就是广播地址

那么就是:11000000.10101000.00000001.000000 00

11000000.10101000.00000001.000000 11

把上面的二进制转换成10进制

得到192.168.1.0是网络地址,192.168.1.3是广播地址。

5. java代码-网络唤醒

先计算被唤醒主机的广播地址

   //根据子网掩码和ip得到主机的广播地址public static String getBroadcastAddress(String ip, String subnetMask){String ipBinary = toBinary(ip);String subnetBinary = toBinary(subnetMask);String broadcastBinary = getBroadcastBinary(ipBinary, subnetBinary);String wholeBroadcastBinary=spiltBinary(broadcastBinary);return binaryToDecimal(wholeBroadcastBinary);}//二进制的ip字符串转十进制private static String binaryToDecimal(String wholeBroadcastBinary){String[] strings = wholeBroadcastBinary.split("\\.");StringBuilder sb = new StringBuilder(40);for (int j = 0; j < strings.length ; j++) {String s = Integer.valueOf(strings[j], 2).toString();sb.append(s).append(".");}return sb.toString().substring(0,sb.length()-1);}//按8位分割二进制字符串private static String spiltBinary(String broadcastBinary){StringBuilder stringBuilder = new StringBuilder(40);char[] chars = broadcastBinary.toCharArray();int count=0;for (int j = 0; j < chars.length; j++) {if (count==8){stringBuilder.append(".");count=0;}stringBuilder.append(chars[j]);count++;}return stringBuilder.toString();}//得到广播地址的二进制码private static String getBroadcastBinary(String ipBinary, String subnetBinary){int i = subnetBinary.lastIndexOf('1');String broadcastIPBinary = ipBinary.substring(0,i+1);for (int j = broadcastIPBinary.length(); j < 32 ; j++) {broadcastIPBinary=broadcastIPBinary+"1";}return broadcastIPBinary;}//转二进制private static String toBinary(String content){String binaryString="";String[] ipSplit = content.split("\\.");for ( String split : ipSplit ) {String s = Integer.toBinaryString(Integer.valueOf(split));int length = s.length();for (int i = length; i <8 ; i++) {s="0"+s;}binaryString = binaryString +s;}return binaryString;}

执行网络唤醒

    /*** 唤醒主机* @param ip         主机ip* @param mac     主机mac* @param subnetMask      主机子网掩码*/public static void wakeUpDevice(String ip,String mac,String subnetMask){ip=ip.trim();mac=mac.trim();subnetMask=subnetMask.trim();String broadcastAddress=getBroadcastAddress(ip,subnetMask);mac = mac.replace("-", "");wakeBy(broadcastAddress,mac,389);}/***   网络唤醒* @param ip            主机ip* @param mac        主机mac* @param port        端口*/private static void wakeBy(String ip, String mac, int port) {//构建magic魔术包String MagicPacage = "FFFFFFFFFFFF";for (int i = 0; i < 16; i++) {MagicPacage += mac;}byte[] MPBinary = hexStr2BinArr(MagicPacage);try {InetAddress address = InetAddress.getByName(ip);DatagramSocket socket = new DatagramSocket(port);DatagramPacket packet = new DatagramPacket(MPBinary, MPBinary.length, address, port);//发送udp数据包到广播地址socket.send(packet);socket.close();} catch (IOException e) {e.printStackTrace();}}private static byte[] hexStr2BinArr(String hexString) {String hexStr = "0123456789ABCDEF";int len = hexString.length() / 2;byte[] bytes = new byte[len];byte high = 0;byte low = 0;for (int i = 0; i < len; i++) {high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4);low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));bytes[i] = (byte) (high | low);}return bytes;}

注意:当跨网段进行唤醒时,即发起唤醒的地址和被唤醒的目的地址不在同一个网段,是否需要做一些调整取决于你的网络配置。我这边的情况是,比如当50网段的服务器发送网络唤醒魔术包到62网段,是行不通的,需要在62网关下增加ip转发广播ip forward-broadcast。

转自 https://my.oschina.net/u/3490860/blog/1613093

java实现远程唤醒一台计算机相关推荐

  1. java实现两台计算机的互联,如何用Java语言实现两台计算机之间的文件传输?

    最近新学习了Java语言,算是一个小白,想用TCP Socket进行网络编程,使得服务器端接受客户端的文件,但是遇到了一个错误,有人知道该怎么解决吗? //这是服务器端的代码 public class ...

  2. 组装一台计算机 java_如何在同一台计算机上安装多个Java版本

    组装一台计算机 java 一段时间以前,我写了一篇文章< 用示例解释Java Lambda表达式>,但是我很容易浏览Java 8,因为我在项目中使用了Java 8,并且允许我安装和使用它. ...

  3. 如何制造一台计算机,编程多年后我开始思考这个问题

    周末,我高中的弟弟问我这样一个问题:"为什么电脑都是从 C 盘开始?A 盘.B 盘哪去了?" 平时他总是问我一些奇怪的问题,其实这是个暴露年龄的问题,作为零五后,他不知道,我不怪他 ...

  4. 国庆期间,我造了台计算机

    每个时代,都不会亏待会学习的人. 对于我们程序员来说计算机的重要性不言而喻,相信大家对计算机内部也有一定的了解. 但是大家有没想过为什么一堆逻辑门组合起来就能运算了?它是如何运作来实现加减法的? 为什 ...

  5. cmd ping 一台计算机名,windows CMD命令查看局域网内所有主机名及IP

    COLOR 0A CLS @ECHOOff Title查询局域网内在线电脑IP :send @ECHO off&setlocal enabledelayedexpansion ECHO 正在获 ...

  6. 一文了解云计算,全世界一台计算机

    云计算,这是自2008年全球金融危机以来全世界最热的词汇之一.世界各国.大街小巷,上至国家元首.下至家中老人,几乎全社会所有人都知道有这样一种新科技,叫"云计算". 自从2006年 ...

  7. 在《我的世界》里从零打造一台计算机有多难?复旦本科生大神花费了一年心血...

    朋友的公众号在送书,晚上八点开奖,她说参与的人有点少,那索性拿过来给我的粉丝白piao一下,哈哈哈哈...:送66本技术书籍 栗子 晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 一块小 ...

  8. 1,Java语言基础-Java语言概述和必要计算机知识

    Java语言基础 Java语言概述 1,Java语言发展史 Java语言本质 Java是面向对象的高级语言,它是由c和c++发展而来. Java发展语言历史概述 Java 是由 James Gosli ...

  9. 国庆期间,我造了台计算机!原理图分享..

    对于我们程序员来说计算机的重要性不言而喻,相信大家对计算机内部也有一定的了解. 但是大家有没想过为什么一堆逻辑门组合起来就能运算了?它是如何运作来实现加减法的? 为什么 cpu 会不停地取指执行?是什 ...

  10. 两台计算机通过传统电话网络,计算机网络的复习题.doc

    计算机网络的复习题 第2章 计算机网络的层次化结构 填空题 ? 开放系统互连参考模型(OSI模型)从底层往高层共分为_______._______.______.传输层.会话层.表示层和应用层七个层次 ...

最新文章

  1. 非锐化掩膜与高提升滤波
  2. flask 第八篇 实例化flask时的参数配置
  3. 如何把Kubernetes config view里的base64编码过后的secret信息还原
  4. HDU 4812 D Tree (点分治) (2013ACM/ICPC亚洲区南京站现场赛)
  5. 六种常用的物联网通信协议
  6. cmake 学习笔记
  7. php唯一索引,索引唯一性扫描(INDEX UNIQUE SCAN)
  8. 高等数学一使用python实现极限后有代码
  9. 判定是否过拟合、欠拟合的一种方式
  10. VS2012下基于Glut OpenGL glEdgeFlag示例程序:
  11. Python——集合与字典练习
  12. mysql悲观锁隔离级别_mysql隔离级别与悲观锁、乐观锁
  13. 【路径规划】基于matlab蚁群算法机器人栅格地图路径规划【含Matlab源码 119期】
  14. oracle 10g for solaris准备工作和实例的删除
  15. unas 下 Transmission 下载使用体会
  16. SpringBoot整合JPA(六)
  17. 机器学习之Python Sklearn——线性回归
  18. 计算机出现蓝屏怎么解决,教你电脑出现蓝屏是怎么回事
  19. java抢红包_Java实现抢红包功能
  20. 华硕无畏15 2023款和华硕无畏15i 2023区别 对比评测选哪个好

热门文章

  1. Python类的私有属性
  2. IntelliJ IDEA 创建 maven 创建java web 项目
  3. 2012我的这一年,2013时不我待
  4. CListCtrl控件的使用指南
  5. 函数式语言(functional language)的相关了解
  6. eclipse订制快捷键
  7. Eclipse自动生成返回值对象的快捷键是什么?
  8. 在Linux环境下安装MYSQL
  9. HDU 1181.变形课-并查集
  10. hibernate映射(一对一、一对多、多对一、多对多)配置 【转】