0. 项目场景:
使用树莓派搭建一台自动化测试台。树莓派与上位机采用C-S架构通过socket进行通信,树莓派作为server, 上位机作为client。 由于测试台需要四处移动,插上网线之后分配的网口ip并不固定, 有的地方也没有以太网口去插网线。考虑将树莓派接入实验室的无线Wifi,在无法获取到eth0 ip时,使用备用的wlan0 ip作为 listening host
1. 问题描述
树莓派与上位机使用socket 通过TCP/IP协议进行通信,树莓派作为server端对有线网口eth0 进行侦听。获取树莓派的IP 作为host 并进行监听的脚本如下
import socket
PORT = 8880
HOST =str(subprocess.check_output("hostname -I | cut -d\' \' -f1", shell = True ),'utf-8').replace('\n','')
g_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
g_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("TCP server listen @ %s:%d !!!" % (HOST, PORT))
g_s.bind((HOST, PORT))
print("Socket Server Listening")
g_s.listen(5)
但是,由于树莓派有时候需要在实验室内移动,有时候无法插网线,但是eth0 并不会因为断开网线而为空。 如果还是使用上面的脚本,则获取到的树莓派IP就不对了。因此也需要实现对无线网口wlan0 进行侦听(当然,前提是树莓派已经配置好Wifi),并且能够自动切换。
2. 解决方案:
在树莓派插上网线和连接到wifi之后,先使用 ifconfig 命令分别读取eth0 和 wlan0 的ip。(注意 grep 'inet ',在inet之后有一个空格)
然后在脚本里对获取的 eth0 inet 进行判断,如果不属于10.xxx网段,则将获取到的wlan0 IP 作为侦听地址,脚本如下所示
import socket
PORT = 8880
if '10.xxx' not in os.popen("ifconfig eth0 | grep 'inet ' | awk '/inet/{print $2}'").read():
HOST = os.popen("ifconfig wlan0 | grep 'inet ' | awk '/inet/{print $2}'").read().replace('\n','')
else:
HOST = os.popen("ifconfig eth0 | grep 'inet ' | awk '/inet/{print $2}'").read().replace('\n','')
g_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
g_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("TCP server listen @ %s:%d !!!" % (HOST, PORT))
g_s.bind((HOST, PORT))
thread_counter = 0
print("Socket Server Listening")
g_s.listen(5)
3. os.popen() 方法
os.popen():
在Linxu语法中,os.popen() 方法用于从一个命令打开一个管道, 它与常用的 os.system() 命令的区别在于返回值不同。os.popen(command) 这种方式, 函数返回一个file 对象,里面的内容就是command输出的内容,可以对整个文件的对象进行操作;而os.system(command) 只是调用系统去执行command。