fix bug scan ip
This commit is contained in:
@@ -1,23 +1,31 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
import threading
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
# Windows: prevent subprocess from opening visible console windows
|
# Windows: prevent subprocess from opening visible console windows
|
||||||
_NO_WINDOW = subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
|
_NO_WINDOW = subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
|
||||||
|
|
||||||
|
# Concurrent ping workers per platform
|
||||||
|
_MAX_WORKERS_WIN = 50
|
||||||
|
_MAX_WORKERS_OTHER = 64
|
||||||
|
|
||||||
|
|
||||||
def _ping_one(ip, is_win):
|
def _ping_one(ip, is_win):
|
||||||
"""Ping a single IP. Returns True if host responds."""
|
"""Ping a single IP. Returns True if host responds."""
|
||||||
try:
|
try:
|
||||||
if is_win:
|
if is_win:
|
||||||
|
# Capture stdout to check for TTL= — more reliable than returncode
|
||||||
|
# on Windows (returncode can be 0 even for "Destination unreachable")
|
||||||
r = subprocess.run(
|
r = subprocess.run(
|
||||||
["ping", "-n", "1", "-w", "500", str(ip)],
|
["ping", "-n", "1", "-w", "500", str(ip)],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=3,
|
timeout=3,
|
||||||
creationflags=_NO_WINDOW
|
creationflags=_NO_WINDOW
|
||||||
)
|
)
|
||||||
|
return r.returncode == 0 and b"TTL=" in r.stdout
|
||||||
elif sys.platform == "darwin":
|
elif sys.platform == "darwin":
|
||||||
r = subprocess.run(
|
r = subprocess.run(
|
||||||
["ping", "-c", "1", "-W", "300", str(ip)],
|
["ping", "-c", "1", "-W", "300", str(ip)],
|
||||||
@@ -49,17 +57,22 @@ def _ping_sweep(network, progress_cb=None):
|
|||||||
is_win = sys.platform == "win32"
|
is_win = sys.platform == "win32"
|
||||||
hosts = list(net.hosts())
|
hosts = list(net.hosts())
|
||||||
total = len(hosts)
|
total = len(hosts)
|
||||||
|
workers = min(_MAX_WORKERS_WIN if is_win else _MAX_WORKERS_OTHER, len(hosts))
|
||||||
|
|
||||||
done_count = [0]
|
done_count = [0]
|
||||||
|
lock = threading.Lock()
|
||||||
alive = []
|
alive = []
|
||||||
|
|
||||||
def _ping_and_track(ip):
|
def _ping_and_track(ip):
|
||||||
ok = _ping_one(ip, is_win)
|
ok = _ping_one(ip, is_win)
|
||||||
|
with lock:
|
||||||
done_count[0] += 1
|
done_count[0] += 1
|
||||||
|
current = done_count[0]
|
||||||
if progress_cb:
|
if progress_cb:
|
||||||
progress_cb(done_count[0], total)
|
progress_cb(current, total)
|
||||||
return (str(ip), ok)
|
return (str(ip), ok)
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=min(64, len(hosts))) as executor:
|
with ThreadPoolExecutor(max_workers=workers) as executor:
|
||||||
futures = [executor.submit(_ping_and_track, ip) for ip in hosts]
|
futures = [executor.submit(_ping_and_track, ip) for ip in hosts]
|
||||||
for f in as_completed(futures):
|
for f in as_completed(futures):
|
||||||
ip_str, ok = f.result()
|
ip_str, ok = f.result()
|
||||||
|
|||||||
7
main.py
7
main.py
@@ -457,11 +457,14 @@ class App(QWidget):
|
|||||||
lbl.setStyleSheet("color: #cdd6f4; font-weight: bold;")
|
lbl.setStyleSheet("color: #cdd6f4; font-weight: bold;")
|
||||||
return lbl
|
return lbl
|
||||||
|
|
||||||
|
# IPs permanently hidden from the device list (never shown in UI)
|
||||||
|
_HIDDEN_IPS = {"192.168.11.102"}
|
||||||
|
|
||||||
def _get_filtered_devices(self):
|
def _get_filtered_devices(self):
|
||||||
"""Return devices filtered based on show_all checkbox."""
|
"""Return devices filtered based on show_all checkbox."""
|
||||||
if self.show_all_cb.isChecked():
|
if self.show_all_cb.isChecked():
|
||||||
return list(self.all_devices)
|
return [d for d in self.all_devices if d["ip"] not in self._HIDDEN_IPS]
|
||||||
excluded = {self.local_ip, self.gateway_ip}
|
excluded = {self.local_ip, self.gateway_ip} | self._HIDDEN_IPS
|
||||||
return [d for d in self.all_devices if d["ip"] not in excluded]
|
return [d for d in self.all_devices if d["ip"] not in excluded]
|
||||||
|
|
||||||
def _refresh_table(self):
|
def _refresh_table(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user