【发布时间】:2021-11-07 10:24:27
【问题描述】:
Wikipedia 说:
Wake-on-LAN (WoL) 是一种以太网或令牌环计算机网络标准,允许通过网络消息打开或唤醒计算机。
但是,在另一部分:
Responding to the magic packet ... 大多数 WoL 硬件在功能上通常默认被阻止,需要在使用系统 BIOS 时启用。在某些情况下,需要从操作系统进行进一步配置,例如通过 Windows 操作系统上的设备管理器网卡属性。
为什么?为什么我们还需要在 OS 中启用 WOL?
问题:
当我实现WOL program 以从本地服务器打开网络(通过 LAN 连接)中的其他 PC 时,我的实际问题出现了。但失败了,因为它需要在 PC 中进行一些额外的配置:
- 配置因操作系统而异(也因版本而异)。
- 有些配置不是永久性的,需要在每次操作系统启动时进行。 (例如:在 Ubuntu 16.04 中我必须运行
ethtool -s eno1 wol g)。
有没有办法绕过操作系统配置,只从 BIOS 设置中启用 WOL?还是代码问题?
WOL 示例:
#include <QByteArray>
#include <QDebug>
#include <QUdpSocket>
#include <thread>
auto sendMagicPacket(QString const& ip, QString const& mac)
{
std::pair<bool, QString> result = {true, ""};
///
/// \note Constants are from
/// https://en.wikipedia.org/wiki/Wake-on-LAN#Magic_packet
///
constexpr auto magicPacketLength = 102;
constexpr auto payloadLength = 6;
constexpr auto payloadValue = static_cast<char>(0xFF);
constexpr auto defaultPort = 9; // Could be 0, 7, 9
char toSend[magicPacketLength];
for (int i = 0; i < payloadLength; ++i)
{
toSend[i] = payloadValue;
}
auto const macSplited = mac.split(':');
auto const macLength = macSplited.size();
for (int j = payloadLength; j < magicPacketLength; j += macLength)
{
for (int i = 0; i < macLength; ++i)
{
toSend[i + j] = static_cast<char>(macSplited[i].toUInt(nullptr, 16));
}
}
QUdpSocket socket;
auto const writtenSize =
socket.writeDatagram(toSend, magicPacketLength, QHostAddress(ip), defaultPort);
if (writtenSize != magicPacketLength)
{
result = {false, "writtenSize(" + QString::number(writtenSize) +
") != magicPacketLength(" +
QString::number(magicPacketLength) +
"): " + socket.errorString()
};
}
return result;
}
int main()
{
for (int i = 0; i < 5; ++i)
{
auto const result = sendMagicPacket("192.168.11.31", "1c:1c:1e:1f:19:15");
if (not result.first)
{
qDebug() << result.second;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
【问题讨论】:
标签: c++ linux windows wake-on-lan