4.5 KiB
Tài liệu Kỹ thuật: Cơ chế Quét IP trên Mạng (Network Scanner)
1. Tổng quan
Thành phần quét IP trong scanner.py dò tìm và liệt kê tất cả thiết bị đang thực sự online trên một dải mạng (ví dụ: 192.168.1.0/24), trả về danh sách chứa IP của từng thiết bị.
Scanner chỉ sử dụng ICMP Ping — thiết bị phải phản hồi ping thì mới được liệt kê. Cơ chế này đảm bảo kết quả chính xác, tránh hiện tượng hiển thị thiết bị đã ngắt kết nối do ARP cache cũ trên router/OS.
Lý do loại bỏ ARP và Scapy: Bảng ARP của hệ điều hành và router giữ cache entry trong nhiều phút, khiến thiết bị đã rút vẫn xuất hiện trong kết quả scan. Ping trực tiếp là phương pháp duy nhất xác nhận thiết bị thực sự đang hoạt động tại thời điểm scan.
2. Luồng hoạt động chính (Hàm scan_network)
scan_network(network)
│
├── stage_cb("ping") ← Thông báo UI bắt đầu quét
│
├── _ping_sweep(network) ← Ping đồng thời toàn bộ host
│ │
│ ├── _ping_one(ip) × N ← Mỗi host 1 thread
│ │
│ └── return [alive IPs]
│
└── return [{"ip": ..., "mac": "N/A"}, ...] ← Sorted by IP
Bước 1 — Ping Sweep
- Gọi
_ping_sweep(network): gửi ICMP Echo Request đồng thời tới toàn bộ host trong dải mạng. - Chỉ các IP có
returncode == 0(phản hồi thành công) mới được đưa vào kết quả.
Bước 2 — Trả về kết quả
- Danh sách sort tăng dần theo IP:
[{"ip": "192.168.1.2", "mac": "N/A"}, ...] - Trường
macluôn là"N/A"— giữ nguyên cấu trúc dict để tương thích với UI và các module khác.
3. Phân tích chi tiết các hàm
_ping_one(ip, is_win)
Ping một IP đơn lẻ, trả về True nếu host phản hồi, False nếu không.
Timeout tối ưu theo nền tảng:
| OS | Lệnh | Timeout wait | Timeout process |
|---|---|---|---|
| Windows | ping -n 1 -w 300 |
300ms | 2s |
| macOS | ping -c 1 -W 300 |
300ms | 2s |
| Linux | ping -c 1 -W 1 |
1s | 2s |
macOS và Linux dùng cùng flag
-Wnhưng đơn vị khác nhau (macOS: ms, Linux: giây) — được xử lý tách biệt theosys.platform.
Windows sử dụng CREATE_NO_WINDOW flag để tránh mở cửa sổ console cho mỗi subprocess.
_ping_sweep(network, progress_cb)
- Tạo
ThreadPoolExecutor(max_workers=len(hosts))— toàn bộ host ping đồng thời, không batching. - Giới hạn an toàn: chỉ chạy với subnet
/24trở xuống (num_addresses <= 256). - Trả về danh sách IP (string) đã phản hồi thành công.
- Gọi
progress_cb(done, total)sau mỗi ping để UI cập nhật thanh tiến độ.
scan_network(network, progress_cb, stage_cb)
- Entry point chính.
stage_cb("ping")thông báo UI giai đoạn hiện tại.- Trả về
list[dict]với format{"ip": str, "mac": "N/A"}, sorted theo IP tăng dần.
4. Hiệu năng
| Thông số | Giá trị |
|---|---|
| Ping workers | len(hosts) (~254, tất cả cùng lúc) |
| Ping timeout — Windows | 300ms |
| Ping timeout — macOS | 300ms |
| Ping timeout — Linux | 1s |
| Process timeout | 2s |
| Tổng thời gian scan /24 | ~1–2s |
5. Ưu & Nhược điểm
Ưu điểm:
- Kết quả chính xác — chỉ thiết bị thực sự online mới xuất hiện, không bị ảnh hưởng bởi ARP cache cũ.
- Không cần quyền Admin/Root.
- Không phụ thuộc thư viện bên ngoài (không cần Scapy, Npcap).
- Tương thích đa nền tảng (Windows/macOS/Linux).
- Nhanh (~1–2s cho /24) nhờ ping toàn bộ host đồng thời.
Nhược điểm:
- Không có thông tin MAC address.
- Thiết bị chặn ICMP (tắt ping) sẽ không bị phát hiện.
- Spawn ~254 process
pingđồng thời trên Windows có overhead cao hơn Unix.