MAC地址远程开机

一、设置

关机模式下,BIOS的电源管理菜单下有Remote Wake Up或Wake on LAN等类似选项的电脑才支持远程开机,若无此选项则不支持远程开机。(假如Remote Wake Up开启后不支持远程开机,请咨询硬件提供商)。

1、进入BIOS

当电脑开机启动时,通过反复按键盘“DELETE”键或“F2”键,进入到主板BIOS设置界面。更多启动主板BIOS设置界面帮助,参考百度。

2、开启唤醒功能

通常到“Power Managment(电源管理)”下寻找如下列选项:
"Boot on LAN";
"Wake on LAN";
"PME Event WakeUp",;
"Resume by MAC LAN";
"Wake-Up by PCI card";
"Wake Up On PCI PME";
"Power On by PCI Card";
"WakeUp by PME of PCI";
"Power On By PCI Devices";
"WakeUp by Onborad LAN";

"PEX boot";
"Resume By PCI or PCI-E Ddevice"或类似的东西,并可以启用它。

可视图形化的UEFI BIOS,可参考下列方式设置:
高级 > 高级电源管理(APM)> 开启 Resume By PCI or PCI-E Ddevice(由pci/pcie设备唤醒)选项。

3、BIOS设置图例

1.以Dell320为例:
进入Power Management Setup——Remote Wake Up设为On

MAC地址远程开机_第1张图片

2.以Dell Latitude D630为例:
进入Power Management——Wake on LAN/WLAN——选择LAN or WLAN

MAC地址远程开机_第2张图片

3.以Dell 1950为例:
Pre-boot Wake On LAN设为Enable

MAC地址远程开机_第3张图片

4.以联想主板为例:
进入Power——Automatic Power ON——Wake On LAN设为Enabled

MAC地址远程开机_第4张图片

5.以华硕主板为例:
进入高级——高级电源管理——开启由PCI/PCIE设备唤醒选项。

MAC地址远程开机_第5张图片

6.以技嘉主板为例:
进入BIOS功能——网络启动——选择Legacy First或UEFI First选项。

MAC地址远程开机_第6张图片

7.以微星主板为例:
进入STANDARD mode——Setup Wake Up Configuration——选择Resume By PCI-E Device选项。

MAC地址远程开机_第7张图片

四、关闭节电功能

远程开机需要网卡保持待机,关机后网卡灯不亮,请检查主板是否开启节能模式。因各厂商对此功能名称定义不一,常见的节电功能选项:
1.假如有Low Power Mode选项,一定要设置为Off

MAC地址远程开机_第8张图片

2.或者是ErP 和 EuP选项,设置为Disabled

MAC地址远程开机_第9张图片

若主板设置后仍无法开机,请参考帮助。
备注:若无法确认BIOS是否包含可设置参数,请使用远程开机检测工具,在内网测试是否可以远程开机或者直接联系主板厂商确认您的设备是否支持远程唤醒!

 

远程开机需要网卡保持待机

远程开机需要网卡保持待机

远程开机需要网卡保持待机

即关机后网卡灯亮。

MAC地址远程开机_第10张图片

如果BIOS设置好,但是网卡灯不亮,就需要进入系统设置。

五、windows、linux检查网卡设置

1 Windows系统:

MAC地址远程开机_第11张图片

MAC地址远程开机_第12张图片

MAC地址远程开机_第13张图片

如果你的系统显示都是英文如下

MAC地址远程开机_第14张图片

请更新最新网卡驱动,就会变为中文并有网络唤醒。

MAC地址远程开机_第15张图片

MAC地址远程开机_第16张图片

MAC地址远程开机_第17张图片

Win10的用户请看这:

检查网卡属性是否缺少网络唤醒。如是,请更新最新网卡驱动;
检查网卡属性后,还需要调整关机设置

MAC地址远程开机_第18张图片

MAC地址远程开机_第19张图片

MAC地址远程开机_第20张图片

关机设置选项默认无法修改,需先点击更改当前不可用的设置

MAC地址远程开机_第21张图片

2 Linux系统:
检查网卡是否支持唤醒功能,输入命令ethtool eth0 打印出网卡的信息。

MAC地址远程开机_第22张图片

Supports Wake-on 值为g,表示网卡支持远程开机;若为d,则不支持。
Wake-on值为g,表示网卡已开启远程唤醒功能;
若为d,则输入命令 ethtool -s eth0 wol g 开启。
命令执行后,输入ethtool eth0,检测是否成功开启wake on lan功能。

 

二、MAC远程开关机代码

#pragma once

#include 
#include 
//#include 

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "advapi32.lib")

class CRemoteControl
{
public:
	CRemoteControl();
	~CRemoteControl();

	static int Startup(char *chMac);
	static int Shutdown(char *chIP, int iTimeOut, bool bForceAppsClosed, bool bRebootAfterShutDown);
};
#include "CRemoteControl.h"



CRemoteControl::CRemoteControl()
{
}


CRemoteControl::~CRemoteControl()
{
}

int CRemoteControl::Startup(char * chMac)
{
	//判断Mac地址格式
	for (char *a = chMac; *a; a++)
	{
		if (*a != '-' && !isxdigit(*a))
		{
			OutputDebugStringA("Mac address must be like this: 00-d0-4c-bf-52-ba");
			return -1;
		}
	}

	//字符串转数组
	int dstaddr[6];
	int i = sscanf(chMac, "%2x-%2x-%2x-%2x-%2x-%2x", &dstaddr[0], &dstaddr[1], &dstaddr[2], &dstaddr[3]
		, &dstaddr[4], &dstaddr[5]);


	if (i != 6)
	{
		OutputDebugStringA("Invalid mac address!");
		return -1;
	}

	//构造Magic Packet (包格式: "FFFFFFFFFFFF" + 重复16编mac地址)
	unsigned char ether_addr[6];
	for (i = 0; i < 6; i++)
	{
		ether_addr[i] = dstaddr[i];
	}

	u_char magicpacket[200];
	memset(magicpacket, 0xff, 6);
	int packetsize = 6;
	for (i = 0; i < 16; i++)
	{
		memcpy(magicpacket + packetsize, ether_addr, 6);
		packetsize += 6;
	}

	//创建广播套接字
	WSADATA WSAData;
	if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)
	{
		OutputDebugStringA("WSAStartup failed");
		return -1;
	}

	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
	{
		OutputDebugStringA("Socket Create error");
		return -1;
	}

	BOOL bOptval = TRUE;
	int iOptLen = sizeof(BOOL);
	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&bOptval, iOptLen) == SOCKET_ERROR)
	{
		OutputDebugStringA("setsocketopt error!");
		closesocket(sock);
		WSACleanup();
		return -1;
	}

	sockaddr_in to;
	to.sin_family = AF_INET;
	to.sin_port = htonl(0);
	to.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);

	//发送魔法包
	if (sendto(sock, (const char*)magicpacket, packetsize, 0, (const struct sockaddr*)&to, sizeof(to)) == SOCKET_ERROR)
	{
		OutputDebugStringA("Send error!");
	}
	else
	{
		OutputDebugStringA("Send success!");
	}

	closesocket(sock);
	WSACleanup();
	return 0;
}

int CRemoteControl::Shutdown(char * chIP, int iTimeOut, bool bForceAppsClosed, bool bRebootAfterShutDown)
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp;

	BOOL fResult;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
		return false;

	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
	if (GetLastError() != ERROR_SUCCESS)
		return false;

	WCHAR wszIP[20];
	memset(wszIP, 0, sizeof(wszIP));
	MultiByteToWideChar(CP_ACP, 0, chIP, strlen(chIP) + 1, wszIP, sizeof(wszIP) / sizeof(wszIP[0]));

	//发送指令,iTimeOut如果小于60,则对方机器关机前会显示“一分钟内关机”
	fResult = ::InitiateSystemShutdown(wszIP, NULL, iTimeOut, bForceAppsClosed, bRebootAfterShutDown);
	if (!fResult)
		return false;

	tkp.Privileges[0].Attributes = 0;
	AdjustTokenPrivileges(hToken, false, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
	if (GetLastError() != ERROR_SUCCESS)
		return false;

	return true;
}

以上为我总结并实践于windows,MAC远程开机可用。

内容出处:他人的代码,某公司的页面,某公司另一页面

你可能感兴趣的:(c/c++,mac)