[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import ttk
import socket
import threading
import queue
import time
class PortScannerGUI:
def __init__(self):
self.root = tk.Tk()
self.root.title("端口扫描工具")
self.root.geometry("600x400")
# 扫描状态
self.scanning = False
self.paused = False
self.ports_queue = queue.Queue()
self.current_port_range = ""
self._create_widgets()
def _create_widgets(self):
# 控制按钮区域
control_frame = ttk.Frame(self.root)
control_frame.pack(pady=10)
self.start_btn = ttk.Button(control_frame, text="开始扫描", command=self.start_scan)
self.start_btn.pack(side=tk.LEFT, padx=5)
self.pause_btn = ttk.Button(control_frame, text="暂停扫描", command=self.pause_scan, state=tk.DISABLED)
self.pause_btn.pack(side=tk.LEFT, padx=5)
self.stop_btn = ttk.Button(control_frame, text="停止扫描", command=self.stop_scan, state=tk.DISABLED)
self.stop_btn.pack(side=tk.LEFT, padx=5)
self.clear_btn = ttk.Button(control_frame, text="清空控制台", command=self.clear_console)
self.clear_btn.pack(side=tk.LEFT, padx=5)
# 进度显示区域
progress_frame = ttk.Frame(self.root)
progress_frame.pack(pady=10)
self.progress = ttk.Progressbar(progress_frame, length=500, mode='determinate')
self.progress.pack()
self.progress_label = ttk.Label(progress_frame, text="当前段进度: 0%")
self.progress_label.pack()
# 控制台输出区域
console_frame = ttk.LabelFrame(self.root, text="扫描控制台")
console_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
self.console = tk.Text(console_frame, height=10)
self.console.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 扫描结果区域
result_frame = ttk.LabelFrame(self.root, text="扫描结果")
result_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
self.result_tree = ttk.Treeview(result_frame, columns=("端口", "状态", "服务"), show="headings")
self.result_tree.heading("端口", text="端口")
self.result_tree.heading("状态", text="状态")
self.result_tree.heading("服务", text="服务")
self.result_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
def scan_port(self, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex(('127.0.0.1', port))
if result == 0:
try:
service = socket.getservbyport(port)
except:
service = "未知"
self.ports_queue.put((port, "开放", service))
sock.close()
except:
pass
def update_gui(self):
while not self.ports_queue.empty():
port, status, service = self.ports_queue.get()
self.result_tree.insert("", tk.END, values=(port, status, service))
self.console.insert(tk.END, f"端口 {port} 是 {status} 的,运行服务: {service}\n")
self.console.see(tk.END)
if self.scanning and not self.paused:
self.root.after(100, self.update_gui)
def start_scan(self):
if not self.scanning:
self.scanning = True
self.paused = False
self.start_btn.config(state=tk.DISABLED)
self.pause_btn.config(state=tk.NORMAL)
self.stop_btn.config(state=tk.NORMAL)
self.progress["value"] = 0
self.console.insert(tk.END, "开始扫描...\n")
def scan_thread():
total_ports = 65535 # 扫描全部端口
chunk_size = 500 # 每个端口段大小
for start_port in range(1, total_ports + 1, chunk_size):
if not self.scanning:
break
end_port = min(start_port + chunk_size - 1, total_ports)
self.current_port_range = f"正在扫描端口段: {start_port}-{end_port}"
self.console.insert(tk.END, f"{self.current_port_range}\n")
self.console.see(tk.END)
for port in range(start_port, end_port + 1):
if not self.scanning:
break
while self.paused:
time.sleep(0.1)
self.scan_port(port)
# 计算当前段的进度
current_progress = ((port - start_port + 1) / chunk_size) * 100
self.progress["value"] = current_progress
self.progress_label.config(text=f"当前段进度: {int(current_progress)}%")
if self.scanning:
self.scanning = False
self.console.insert(tk.END, "扫描完成!\n")
self.start_btn.config(state=tk.NORMAL)
self.pause_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.DISABLED)
self.progress_label.config(text="当前段进度: 100%")
threading.Thread(target=scan_thread, daemon=True).start()
self.update_gui()
def pause_scan(self):
self.paused = not self.paused
self.pause_btn.config(text="继续扫描" if self.paused else "暂停扫描")
status = "暂停" if self.paused else "继续"
self.console.insert(tk.END, f"扫描{status}...\n")
if not self.paused:
self.console.insert(tk.END, f"继续{self.current_port_range}\n")
def stop_scan(self):
self.scanning = False
self.paused = False
self.start_btn.config(state=tk.NORMAL)
self.pause_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.DISABLED)
self.console.insert(tk.END, "扫描已停止!\n")
self.progress_label.config(text="当前段进度: 0%")
def clear_console(self):
self.console.delete(1.0, tk.END)
self.result_tree.delete(*self.result_tree.get_children())
self.progress["value"] = 0
self.progress_label.config(text="当前段进度: 0%")
def run(self):
self.root.mainloop()
if __name__ == "__main__":
app = PortScannerGUI()
app.run()