为什么WOL(Wake On Lan)与操作系统有关?

Why WOL(WakeOnLan) Is Releated To Operating System?

Wikipedia 说:

Wake-on-LAN (WoL) is an Ethernet or Token Ring computer networking standard that allows a computer to be turned on or awakened by a network message.

但是,在另一节中:

Responding to the magic packet ... Most WoL hardware functionally is typically blocked by default and needs to be enabled in using the system BIOS. Further configuration from the OS is required in some cases, for example via the Device Manager network card properties on Windows operating systems.

为什么?为什么我们还需要在 OS 中启用 WOL?

问题:

当我实施 WOL program 从本地服务器打开网络(通过 LAN 连接)中的其他 PC 时,我的实际问题出现了。但是失败了,因为它需要在PC上进行一些额外的配置:

  1. 配置从 OS 到 OS(以及从版本到版本)不同。
  2. 有些配置不是永久性的,需要在每次 OS 启动时进行。 (例如:在 Ubuntu 16.04 中我不得不 运行 ethtool -s eno1 wol g)。

有什么方法可以绕过 OS 配置,只从 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));
  }
}

OS 仅涉及到没有为所有硬件启用 WoL 的标准化方法。因此,您通常需要特定硬件的设备驱动程序才能启用硬件的功能。加载 OS 通常会给你这样的设备驱动程序。

运行 ethtool 每次启动都应该是相当微不足道的,特别是因为(最后,如果没记错的话)运行 它两次(或更多)应该是无害的,所以你可以将它添加到(对于一个例子)你的.bashrc。如果你需要确保它真的只在你启动时发生一次,而不是每次你登录时,你可以添加一个初始化脚本来做到这一点。 man init-d-script 应该会让你很轻松。

您必须启用它,因为大多数 BIOSes 默认禁用它,因此除非您启用它,否则它不会工作。

至于为什么默认禁用它:不太确定,但我的猜测是,这仅仅是因为大多数人不使用它。