在将我们的开发团队从 Windows 7 升级到 Windows 10 后,我们遇到了 ARP 缓存问题,其中一台计算机缓存了正确的 IP-MAC 映射,但由于目标计算机电源循环期间连接失败,类型无效。在 Windows 10 上(而不是 Windows 7 上),在清除 ARP 缓存之前无法连接到目标计算机。我可以重现该问题,如下所示,其中 10.10.10.10 是正确的 IP 地址,01:23:45:67:89:AB 是相关目标计算机的正确 MAC 地址:
从关闭目标机器开始,并在整个测试过程中对其进行 ping 操作:
ping -t 10.10.10.10
Ping 回复“请求超时”,并且 ARP 缓存包含预期内容
10.10.10.10 00:00:00:00:00:00 invalid
打开目标机器。Ping 开始收到回复,ARP 缓存更新为
10.10.10.10 01:23:45:67:89:AB dynamic
到目前为止,一切都很好。
关闭目标机器。Ping 开始报告“请求超时”,并且 ARP 缓存仍然存在
10.10.10.10 01:23:45:67:89:AB dynamic
大约 40 秒后,ping 命令会针对一个请求回复“目标主机不可达”,然后返回报告“请求超时”,ARP 缓存将更改为
10.10.10.10 01:23:45:67:89:AB invalid
打开目标机器的电源,ping(和任何其他连接)将无法找到它,直到您清除 ARP 缓存,或者至少删除具有无效类型的正确 IP-MAC 映射的问题条目。
鉴于开发环境中的目标计算机在开发过程中确实需要电源循环,我该如何防止 ARP 缓存进入此状态?手动操作 ARP 缓存是不可持续的,在迁移到 Windows 10 之前没有人报告过此问题。
Windows 7 的功能正如我们所期望的那样,也就是说,正如我们所希望的那样:ARP 缓存经历与上述相同的阶段。在目标开机之前,Ping 首先回复“目标主机无法访问”,而 Windows 10 则回复“请求超时”,并且在关机后不断返回“目标主机无法访问”,而 Windows 10 只报告一次。当机器开机时,连接立即建立,ARP 缓存返回
10.10.10.10 01:23:45:67:89:AB dynamic
无需先清除任何条目。
开发人员的具体设置是一台 Windows 工作站,通过一个简单的非托管 8 端口千兆交换机连接到多台 Beaglebone Black(基于 ARM 的小型嵌入式主板,运行 Linux)。IP 地址由保留的 DHCP 分配,每次打开 Beaglebones 电源时都会成功获取地址。当一台 Windows 10 机器有需要删除的无效 ARP 条目时,ARP 缓存中没有 Beaglebone 的其他机器可以成功连接到目标机器。
答案1
这么多年了还是这样。做嵌入式开发的时候很烦。
至少我找到了一些半解决方案。
当链接断开时,Win10 会立即删除接口上的所有 ARP 缓存。因此,在嵌入式设备断电时,这会刷新缓存。这不是问题。
问题出现在 Windows 尝试在设备能够响应之前对其进行 ARP 时。这会导致 ARP 缓存失败(“不完整”)。即使设备上线并会响应 ARP 请求,一段时间内也不会发出此类请求。这种情况要么需要再次硬链接断开并重新 ARP,这相当于刷新 ARP 缓存,要么需要等待大约一分钟才能让 Win10 重新 ARP。
一个简单但通常令人恼火的解决方案是添加静态 ARP 条目。这很烦人,因为 a) 您需要提前知道这一点,并且 b) 您需要是 PC 的管理员才能执行此操作。
另一个解决方法是在线路中安装一个以太网交换机,保护 Win10 PC 免受链路断开的影响,并通过以下方式禁用邻居不可达检测(以管理员身份):
netsh 接口 ipv4 设置接口 nud=disabled 存储=持久
现在,尝试访问启动设备失败不会使缓存降至“不完整”。
这两种解决方案都不能令人满意,但它们确实能让你取得一些进步。
霍皮