通过OpenWrt与光猫单线利用,并通过UDPxy组播转单播,实现了在局域网内任意设备观看IPTV,但是在使用一段时间后网络会断网,但IPTV却可以正常观看,也看不出是哪出了问题,感觉是网络“串了”,看不懂日志也解决不了,但是重启OpenWrt才能恢复网络连接,而且这样的情况会经常有,有时几天有时十几、二十几天,我在家还好,网络不行了就重启一下系统。如果我不在家,家里人就得拔电重插,这样达到重启OpenWrt系统的目的。两种方法都得手动重启,很麻烦。
定时重启
后来就想到使用OpenWrt自带的定时重启。设定为每天重启一次,这样最大化的减少间隔。但感觉这有点“浪费”,并不是对症的靶向治疗。而且这个不能保证百分百有效,因为网络无法连接是不定时的出现情况,前面也说了有时几天有时十几、二十几天,但不能保证以后就是这种规律,但是不排除这种情况:系统刚重启完网络可能就不能用了, 只能在发现后手动再次重启。治标不治本。
系统启动
后来就想到在检测到网络无法连接时自动重启OpenWrt不就解决了吗?
使用开机启动的方法将重启脚本设置成开机启动,但是这只能保证脚本开机自启动成功,不能保证持续运行,万一脚本意外中断就无法检测网络。遂放弃此方法。
系统服务
要找到一个自动启动而且要守护运行的方法,那就只有一个办法了那就是系统服务的方法了。
系统服务最重要的就是能守护进程,就像WindOpenWrtws系统的服务一样可以设置重启策略,这样一来,即便脚本意外退出,系统服务也会将它重启保持持续运行。
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
PROG=/root/check-network
start_service() {
cat >$PROG < \$REBOOT_LOG
# 尝试访问的URL
CHECK_URL="https://www.baidu.com"
# 连续失败次数
FAILURE_COUNT=0
# 高级配置:5分钟之内达到重启次数2次,往后不会再重启
# 逻辑:
# 1.每次执行重启前记录当前时间
# 2.每次需要重启前先判断最近2次的重启间隔是否大于5分钟,大于5分钟则重启,小于等于5分钟则不重启
TIME_INTERVAL=\$((5 * 60))
REBOOT_TIME=2
while true; do
# 使用curl尝试访问外部网站,并获取HTTP状态码,超时时间5秒
STATUS_CODE=\$(curl -m 5 -o /dev/null --silent --head --write-out '%{http_code}\n' "\$CHECK_URL")
# 检查状态码是否为200
if [ "\$STATUS_CODE" != "200" ]; then
# 如果不是200,则增加失败次数
FAILURE_COUNT=\$((FAILURE_COUNT + 1))
# 记录到日志文件
echo "\$(date): Failed to connect (\$STATUS_CODE). Count: \$FAILURE_COUNT" >> "\$LOGFILE"
# 如果连续失败两次,则进入重启判断环节
if [ "\$FAILURE_COUNT" -eq 2 ]; then
# 重置失败次数
FAILURE_COUNT=0
# 判断是否需要重启
if [ "\$(wc -l < \$REBOOT_LOG)" -ge \$REBOOT_TIME ];then
if [ "\$(tail -n \$REBOOT_TIME \$REBOOT_LOG | sed 's/\n/ /g' | awk -v k=\$REBOOT_TIME '{print \$k - \$1}')" -ge \$TIME_INTERVAL ];then
echo "\$(date): Restarting system due to continuous network failures." >> "\$LOGFILE"
echo "\$(date +%s)" >> \$REBOOT_LOG
reboot
fi
else
echo "\$(date): Restarting system due to continuous network failures." >> "\$LOGFILE"
echo "\$(date +%s)" >> \$REBOOT_LOG
reboot
fi
fi
else
# 如果连接成功,则重置失败次数
FAILURE_COUNT=0
# 连接成功不输出日志
# echo "\$(date): Network connection is good (\$STATUS_CODE)." >> "\$LOGFILE"
fi
# 等待10秒再次检查
sleep 10
done
EOF
chmod +x $PROG
procd_open_instance
procd_set_param command $PROG
procd_set_param respawn
procd_close_instance
}
这个脚本的作用是:每10秒检测一次网络连接,如果连续两次检测到无法连接网络则会重启,而且限制在五分钟内只能重启两次。这就避免了非路由器故障而导致的无网络连接的循环重启。
为什么使用curl的方法而不是ping呢?因为我在路由器上安装着小猫咪,使用小猫咪的话,ping的都是小猫咪,也就无法检测网络连接状态了。
将以上内容上传到OpenWrt的/etc/init.d
目录下,名称随意,并赋予读取、执行权限。
注意:前要将以上内容转换成Linux格式的换行符Unix(LF)
格式再上传到OpenWrt上。我这是使用的Notepad++,其它自行解决。
然后在OpenWrt里找到系统-启动项
,找到添加的服务,并启用该服务。这里提一下,显示启用
时为已开启开机自启动。这样就可以在系统启动时启动该服务。点击启动
则立即开始运行,即在当前状态下开始运行。
或者使用以下命令控制该服务:
启用开机启动
/etc/init.d/netwok-test enable
禁用开机启动
/etc/init.d/netwok-test disable
手动启动
/etc/init.d/netwok-test start
手动停止
/etc/init.d/netwok-test stop
查看状态
/etc/init.d/netwok-test status