目录
背景目标为什么需要做自动网络切换网络切换手段
网络环境实现思路和代码部署脚本开机自动执行附录开机时自动连接两个网络连接两个网络时的路由问题Tailscale指定网络出口
背景
目标
学校实验室有两个网络环境,我电脑使用网线连接稳定但低速的网络A,使用WiFi连接高速但不稳定的网络B。因此,我希望平时使用网络B,当网络B不稳定时自动切换到网络A。
为什么需要做自动网络切换
由于网络B需要使用帐号登录,其不稳定主要是由于间歇性登录过期导致的。被退出登录时虽然网络有连接,但无互联网访问,这导致Windows不会自动切换到另一个网络中。
而且由于我经常需要远程连接到该电脑,因此必须寻找一种自动的方法解决该问题。
我也考虑过使用自动登录脚本,但问题有概率是网络B本身的故障,这时候自动登录就也会失效,因此切换到网络A是更加稳妥的方案。
网络切换手段
可选的手段很多,例如:关闭WiFi适配器、断开当前WiFi、路由表删掉到WiFi接口的路由、控制路由跃点等,我选择使用控制路由跃点的方式。
选择该方式主要是为了远程连接时能够更方便地重新登录和使用网络B。
网络环境
连上有线网络A和无线网络B并登录后,通过ipconfig指令看到网络配置情况如下:
以太网适配器 Ethernet:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . :
IPv4 地址 . . . . . . . . . . . . : 192.168.183.62
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.183.254
无线局域网适配器 WiFi6:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . :
IPv4 地址 . . . . . . . . . . . . : 172.27.60.26
子网掩码 . . . . . . . . . . . . : 255.255.0.0
默认网关. . . . . . . . . . . . . : 172.27.255.254
route print指令查看路由表,呈现如下关键信息:
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 192.168.183.254 192.168.183.62 25
0.0.0.0 0.0.0.0 172.27.255.254 172.27.60.26 50
默认情况下,有线网络A(192.168)的跃点数相较于无线网络B(172.27)更低,因此Windows会优先使用有线网络A。
要优先使用无线网络B,但保持有线网络A的连接,最方便的方法是减少无线网络B的跃点数。 我们将无线网络B的跃点数设置为小于25,即可优先使用无线网络B:
# 需要管理员权限
Get-NetIPInterface -InterfaceAlias WiFi6 | Set-NetIPInterface 21
或者在控制面板中修改:
实现思路和代码
通过跃点数可以轻松控制多个网络的优先级,因此当无线网络B连接异常时,我们通过调整跃点数使得优先使用网络A。
以下为通过Powershell脚本的实现:
# auto_swich.ps1
# 定义WiFi和以太网的接口名称
$wifiInterface = "WiFi6"
$ethernetInterface = "Ethernet"
# 定义网络异常时WiFi的跃点值(Metric)
$wifiMetricHigh = 10000
# 定义检查的目标地址 (阿里云DNS)
$testAddress = "223.6.6.6"
# 定义检查间隔(秒)
$checkInterval = 60 * 3
# 等待WiFi连接
while (-not (Get-NetIPInterface -InterfaceAlias $wifiInterface | Where-Object { $_.ConnectionState -eq "Connected" })) {
Write-Host "等待WiFi连接..." -ForegroundColor Yellow
Start-Sleep -Seconds 30
}
Write-Host "WiFi已连接,设置优先使用WiFi,并开始执行循环检查连接情况..." -ForegroundColor Green
Get-NetIPInterface -InterfaceAlias $ethernetInterface | Set-NetIPInterface -InterfaceMetric $ethernetMetric
Get-NetIPInterface -InterfaceAlias $wifiInterface | Set-NetIPInterface -InterfaceMetric $wifiMetricLow
# 循环检查
while ($true) {
Write-Host "将在 $checkInterval 秒后检查..." -ForegroundColor Cyan
Start-Sleep -Seconds $checkInterval
Write-Host "正在检查网络连接状态..." -ForegroundColor Cyan
$wifiConnected = Test-Connection -ComputerName $testAddress -Count 5 -Quiet # 检查目标地址是否可访问 五次有一次有响应则认为连接正常
if (!$wifiConnected) {
Write-Host "无网络访问,设置WiFi高跃点..." -ForegroundColor Yellow
Get-NetIPInterface -InterfaceAlias $wifiInterface | Set-NetIPInterface -InterfaceMetric $wifiMetricHigh
}
}
部署脚本开机自动执行
由于脚本需要使用管理员权限,因此使用任务计划程序部署。 按Win+R打开运行,输入taskschd.msc确定,打开任务计划程序窗口,按照下图将该脚本添加为开机启动的计划任务。
附录
这里记录了一些相关问题的解决方案
开机时自动连接两个网络
Win10/11下WIFI无法自动/主动连接的解决方法
连接两个网络时的路由问题
连接两个网络时,通过设置路由控制访问网络资源时使用的网络出口,例如:
# 需要管理员权限
route add 192.168.0.0 mask 255.255.0.0 192.168.183.254 -p # 访问内网设备走192.168.*
route add 192.168.167.115 mask 255.255.255.255 172.27.255.254 -p # 172.27校园网登录页面
route add 18.0.0.0 mask 255.0.0.0 192.168.183.254 -p # 访问ieeexplore.ieee.org走192.168教育网认证
Tailscale指定网络出口
尝试了N种方法,包括查Tailscale文档、各种设置路由表(控制到DERP服务器或是直连目标或是虚拟ip的路由都不行),发现连接两个网络时无法使得Tailscale单独使用一个网络出口(例如Tailscale使用WiFi,其他流量从有线网卡出),只能通过控制路由表中0.0.0.0的跃点数控制出口。
甚至还有将DERP的地址路由到某一出口的后,就算0.0.0.0也是该出口,Tailscale却依然使用另一出口的奇怪现象(゚Д゚≡゚Д゚)。
有人找到了解决方法麻烦告知我一下谢谢TAT