我有 3 个 IP 块和 3 个 Cisco 交换机。每个交换机都有自己的 IP 块 - 10.45.100.0/24、10.45.101.0/24 和 10.45.102.0/24
我有一台位于 10.45.100.0/24 块上的 PC。我可以用 C# 唤醒此 IP 块中的全部计算机(包括 IP 地址、Mac 地址、子网、端口)。
但是当我尝试从不同的 IP 块唤醒另一台机器时,它不起作用。
这是网络问题还是代码问题?我该如何解决?
答案1
这是一个根本问题:睡眠呼吸暂停仅在子网内有效,因为 WOL 魔术包不是有效的 IP 包,因此无法在本地 LAN 之外进行路由。
维基百科条目概述了此问题的解决方案(子网定向广播),但我从未见过实际操作。解决此问题的另一种方法可能是创建一个 WOL 代理,将 WOL 数据包转发到其他子网(即作为 UDP 数据包)。
答案2
如果您有三个不同的子网,那么如果没有路由器,这些子网就无法相互通信。
这是 100% 故意为之。
你尝试执行 WOL 的机器的默认网关必须明确地知道如何到达其他子网,否则它会将您的数据包发送到互联网上,然后您的 ISP 会立即丢弃它。
因此,您有两个选择:
- 在子网之间设置正确的路由
- 将子网掩码减小到 255.255.0.0 (/16) 之类的值,以便所有计算机都位于同一子网中。我不建议这样做,因为我确信您的计算机彼此之间划分子网是有原因的。
答案3
一个可能的解决方案:在控制 PC 上添加第二张(甚至第三张)NIC 卡,然后配置其他 IP 地址以直接与其他路由器连接。然后,魔术包将根据 WOL 命令中的目标 IP(IP、MAC、子网、端口)传递关联的 NIC。
答案4
我有一个解决方案,但它适用于固定 IP 地址。我不知道,但也许可以更改代码来修复动态地址的问题。
您只需要将一个魔术包发送到您计算机的固定地址即可。我创建了一个小实用程序。
我的子网是 172.17.111.0/24,数据包从 172.17.105.0/24 发送
class Program
{
static readonly Tuple<string, byte[]>[] Addr = {
new Tuple<string, byte[]>("**-**-30-9D-98-61", new byte[] { 172, 17, 111, 91 }),
new Tuple<string, byte[]>("**-**-D9-7B-9D-E9", new byte[] { 172, 17, 111, 70 }),
};
static void Main(string[] args)
{
var id = args.Length > 0 ? int.Parse(args[0]) : 0;
WolClass client = new WolClass();
client.Connect(new IPAddress(Addr[id].Item2), 0x9);
client.SetClientToBrodcastMode();
//set sending bites
int counter = 0;
//buffer to be send
byte[] bytes = new byte[1024];
//first 6 bytes should be 0xFF
for (int y = 0; y < 6; y++)
bytes[counter++] = 0xFF;
//now repeate MAC 16 times
for (int y = 0; y < 16; y++)
{
int i = 0;
for (int z = 0; z < 6; z++)
{
bytes[counter++] = byte.Parse(Addr[id].Item1.Substring(i, 2),
NumberStyles.HexNumber);
i += 3;
}
}
//now send wake up packet
client.Send(bytes, 1024);
}
}
public class WolClass : UdpClient
{
//this is needed to send broadcast packet
public void SetClientToBrodcastMode()
{
if (this.Active)
this.Client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast, 0);
}
}