我正在为程序编写后端,该程序需要能够ping网络上的所有设备以查看它们是否存在。该后端在烧瓶插座上运行。我编写了一个简单的测试脚本,该脚本使用threadExecutor和Futures来完成此任务,以加快该过程。
import platform
import subprocess
import netifaces as ni
import concurrent.futures
import socket
baseIP = ni.ifaddresses('enp4s0')[ni.AF_INET][0]['addr']
prefix = '.'.join(baseIP.split('.')[0:3])
aliveIPs = []
def ping(ip):
command = ['ping', '-c 1', '-w 5', ip]
print(ip)
if(subprocess.call(command) == 0):
return socket.gethostbyaddr(ip)
else:
return ''
ips = [prefix + '.' +str(i) for i in range(0,255)]
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for ip in ips:
futures.append(executor.submit(ping, ip=ip))
for future in concurrent.futures.as_completed(futures):
res = future.result()
if(res != ''):
aliveIPs.append(res)
print(aliveIPs)
此代码在我的PC上与python3一起运行时效果很好,并为我提供了网络上的设备列表。
但是,当我在我的flask应用程序中实现此代码时,将来永远都无法完成,导致它挂在它尝试扫描的第一个ip上。以下代码来自我的flask应用程序。
def ping(ip):
print(ip)
proc = subprocess.run(['ping', '-c 1', '-w 5', ip])
if(proc == 0):
print("alive")
return socket.gethostbyaddr(ip)
else:
print("none")
return ''
"""
gets a list of available hosts in the network for a connection
"""
def update_worker_list(executor):
print("updating")
network_device = get_network_info()['net_name']
ip = ni.ifaddresses(network_device)[ni.AF_INET][0]['addr']
ipPrefix = '.'.join(ip.split('.')[0:3])
alive_ips = []
ips = [ipPrefix + '.' + str(i) for i in range(0, 255)]
futures = []
for ip in ips:
futures.append(executor.submit(ping, ip=ip))
for future in concurrent.futures.as_completed(futures):
res = future.result()
if(res != ''):
alive_ips.append(res)
print(alive_ips)
此处的executor参数是flask-executor pip包中的flask_executor。它的设置如下:
app = Flask(__name__)
app.config['SECRET_KEY'] = DEV_SECRET
app.config['DEBUG'] = True
app.config['EXECUTOR_TYPE'] = 'thread'
app.config['EXECUTOR_MAX_WORKERS'] = 20
executor = Executor(app)
我最初使用python提供的执行程序尝试了此操作,但这导致了相同的错误。 以下是update_workers_list函数向STDOUT的输出:
updating
192.168.8.0
Do you want to ping broadcast? Then -b. If not, check your local firewall rules.
none
我对寻找未来无法解决的任何想法。
答案 0 :(得分:0)
因此,在浏览了flask-socketIO的源代码之后,我发现socketIO喜欢占用线程。这意味着您必须自己使用gevent或eventlet猴子修补它以使用另一个。 this帖子对此进行了很好的解释,并引导我修复了我的错误。