ARM40-A5应用——ARM40网络应用场景3
2018.9.15
本文接《ARM40-A5应用——ARM40网络应用场景2》。
在上文应用场景4中,有个缺陷,例如:正在使用无线,此时发生外部干涉(如在界面切换了S40network route 或者S41network route),有线就通了,但是应用场景4的程序仍旧会使用无线,而不会切换到有线。
若要有线通了后,能及时切换到有线,需不断监控每个网路的情况,见本文应用场景5。
八、应用场景5——双有线+无线自动切换
8.1、代码
首先我们看 /etc/network/if-public-network.sh,它主要使用在不需要切换的场合。或者用于在 /etc/network/if-auto-switch.sh 前选择网路。其内容为如下三种之一,分别用于选择ppp、eth0、eth1。
#!/bin/sh
#/etc/network/if-public-network.sh
#2G
/etc/ppp/pon-M26-auto.sh &
#!/bin/sh
killall pon-M26-auto.sh
killall pppd
/etc/init.d/S40network route
#!/bin/sh
killall pon-M26-auto.sh
killall pppd
/etc/init.d/S41network route
有线eth0、有线eth1、无线ppp0三者之间自动切换,流程详见if-auto-switch.sh代码和图示。
建立 /etc/network/if-auto-switch.sh 文件:
touch /etc/network/if-auto-switch.sh
chmod 755 /etc/network/if-auto-switch.sh
其内容为:
#!/bin/sh
#automatically switch between eth0 and ppp0 network
dns1="223.5.5.5" #aliyun dns
dns2="223.6.6.6" #aliyun dns
echo "NULL" > /var/log/if-channel-live
ETH0="NO"
ETH1="NO"
while true
do
sleep 10
if [ $(cat /sys/class/net/eth0/carrier) -eq 1 ]; then #eth0 is link up
ping -c 1 -w 10 -I eth0 $dns1 >/dev/null #ping dns1,1 count,timeout is 10s
if [ $? -ne 0 ]; then #ping request timed out
ping -c 1 -w 10 -I eth0 $dns2 >/dev/null #ping dns2,1 count,timeout is 10s
if [ $? -ne 0 ]; then #ping request timed out
ETH0="NO"
else #dns2 connected
ETH0="YES"
fi
else #dns1 connected
ETH0="YES"
fi
if [ $ETH0 == "YES" ]; then
echo "ETH0" > /var/log/if-channel-live
procnum=`ps -ef|grep "pon-M26-auto.sh"|grep -v grep|wc -l`
if [ $procnum -ne 0 ]; then #if pon-M26-auto.sh is exist
killall pon-M26-auto.sh
killall pppd
fi
fi
else
ETH0="NO"
fi
if [ $(cat /sys/class/net/eth1/carrier) -eq 1 ]; then #eth1 is link up
ping -c 1 -w 10 -I eth1 $dns1 >/dev/null #ping dns1,1 count,timeout is 10s
if [ $? -ne 0 ]; then #ping request timed out
ping -c 1 -w 10 -I eth1 $dns2 >/dev/null #ping dns2,1 count,timeout is 10s
if [ $? -ne 0 ]; then #ping request timed out
ETH1="NO"
else #dns2 connected
ETH1="YES"
fi
else #dns1 connected
ETH1="YES"
fi
if [ $ETH1 == "YES" ]; then
echo "ETH1" > /var/log/if-channel-live
procnum=`ps -ef|grep "pon-M26-auto.sh"|grep -v grep|wc -l`
if [ $procnum -ne 0 ]; then #if pon-M26-auto.sh is exist
killall pon-M26-auto.sh
killall pppd
fi
fi
else
ETH1="NO"
fi
if [ $ETH0 == "NO" -a $ETH1 == "NO" ]; then
procnum=`ps -ef|grep "pon-M26-auto.sh"|grep -v grep|wc -l`
if [ $procnum -eq 0 ]; then
echo "NULL" > /var/log/if-channel-live
/etc/ppp/pon-M26-auto.sh & #if success, echo "PPP0" > /var/log/if-channel-live
else
#wc -l /var/log/pppd-recall.log #good for test print
pingnum=`cat /var/log/pppd-recall.log|wc -l` #ping ppp0, 5 times unconnected
if [ $pingnum -ge 5 ]; then #unconnected 5 times
echo "NULL" > /var/log/if-channel-live
killall pon-M26-auto.sh
killall pppd
if [ $(cat /sys/class/net/eth0/carrier) -eq 1 ]; then
/etc/init.d/S40network route #set eth0 iproute
ETH0="YES"
elif [ $(cat /sys/class/net/eth1/carrier) -eq 1 ]; then
/etc/init.d/S41network route #set eth1 iproute
ETH1="YES"
else
/etc/ppp/pon-M26-auto.sh &
fi
fi
fi
fi
sleep 50
done
如果eth0和eth1都不通,才会用ppp0,而一端eth0或eth1通了,就会切换到有线,而不再使用ppp0了。
ppp0连接建立后,会设定 /var/log/if-channel-live 为"PPP0"。
eth0连接建立后,会设定 /var/log/if-channel-live 为"ETH0"。
ppp0连接失败,会设定 /var/log/if-channel-live 为"NULL"。
其他应用程序可以通过访问if-channel-live,来获取设备目前联网的方式:PPP0、ETH0、NULL(未联网)。
cat /var/log/if-channel-live
8.2、代码解析
代码解析下面的图示:
测试示例:
九、上电自动运行
若要上电自启动 /etc/network/if-auto-switch.sh,则修改/etc/profile.local 。
logintty=$(tty|grep -c "console")
if [ $logintty -eq 1 ]; then # ssh,telnet can't get into this line
/etc/network/if-public-network.sh
/etc/network/if-auto-switch.sh &
fi
注意 /etc/profile 文件的最后是:
source /etc/profile.local
十、常见问题
1、本例子适于含有eth0、eth1、ppp0的场景,其它场景都需适当改动。
例:若无eth1,则 cat /sys/class/net/eth1/carrier
会报错导致 if-auto-switch.sh退出。若无eth0,则 cat /sys/class/net/eth0/carrier
会报错。
2、Linux系统的多个网路,无法同时连接外网。并且eth0、eth1不应设置为同一网段,例如都设置为 192.168.6.* 网段,Linux是不支持的。
参考文章:
ARM40-A5应用——GPRS模块ppp拨号上网
ARM40-A5应用——ARM40网络应用场景1
ARM40-A5应用——ARM40网络应用场景2
荟聚计划:共商 共建 共享 Grant