当我开始用 scapy 嗅探时,Tkinter 崩溃了

Tkinter crashes when I start sniffing with scapy

所以我正在尝试编写一个程序,当您按下 "Start sniffing" 它开始嗅探数据包并将其打印到控制台,当您按下 "Stop sniffing" 它停止嗅探。这是我写的代码:

from tkinter import *
from scapy.all import *
from scapy.arch.windows.compa import * """Adds stop_filter to sniff because 
its not in scapy-python3"""
root = Tk()
Switch = False
def stopbutton():
   global Switch
   Switch = True
def stopsniffing(x):
    global Switch
    return Switch    
def action(packet):
   try:
      print ("%s went to %s"%(packet[IP].src, packet[IP].dst))
   except:
     pass
 def startsniffing():
    sniff(filter="host 192.168.0.48", prn=action, stop_filter=stopsniffing)
 button = Button(text="Start sniffing", command=startsniffing).pack()
 button2 = Button(text="Stop sniffing", command=stopbutton).pack()
 root.mainloop()

我的问题是,当我按下“开始嗅探”时,它开始嗅探,但其他一切都没有响应。

sniff() 是 long-运行ning 函数,所以程序不能 return 到 mainloop() 从系统获取 key/mouse 事件,将事件发送到小部件,重绘小部件 - 所以它看起来像冻结了。你必须使用 threading 到 运行 sniff()

import tkinter as tk
from scapy.all import *
from scapy.arch.windows.compa import *
"""Adds stop_filter to sniff because its not in scapy-python3"""
import threading

# --- functions ---

def sniffing():
    print('DEBUG: before sniff')
    #sniff(filter="host 192.168.0.48", prn=action, stop_filter=stop_sniffing)
    sniff(prn=action, stop_filter=stop_sniffing)
    print('DEBUG: after sniff')

def action(packet):
    try:
        print("%s went to %s" % (packet[IP].src, packet[IP].dst))
    except Exception as e:
        print(e)

def stop_sniffing(x):
    global switch
    return switch

# ---

def start_button():
    global switch
    global thread

    if (thread is None) or (not thread.is_alive()):
        switch = False
        thread = threading.Thread(target=sniffing)
        thread.start()
    else:
        print('DEBUG: already running')

def stop_button():
    global switch

    print('DEBUG: stoping')

    switch = True

# --- main ---

thread = None 
switch = False

root = tk.Tk()

tk.Button(root, text="Start sniffing", command=start_button).pack()
tk.Button(root, text="Stop sniffing", command=stop_button).pack()

root.mainloop()

顺便说一句: 如果你这样做 var = Widget(...).pack() 那么你将 None 分配给 var 因为 pack()/grid()/place() return s None。如果你不需要 var 那么你可以跳过它

Widget(...).pack() 

如果你需要var那么你必须分两行

var = Widget(...)
var.pack()