wxPython:使用wxButton停止线程化

时间:2013-10-06 01:56:52

标签: python multithreading

如何通过单击wxButton来停止线程化?

这是我的代码:

def startMonitor(self,event):       
    selectedInterface = self.interfaces_cblist.GetValue()
    Publisher().sendMessage(("test"),selectedInterface) 
    self.Close()
    selectInterfaceStr = str(selectedInterface) 
    if len(selectedInterface) == 0:
        noSelect_error = wx.MessageDialog(None,"Please select an interface","",wx.OK|wx.ICON_ERROR)
        noSelect_error.ShowModal()
    else:       
        monitorStarted = wx.MessageDialog(None,"Monitor on %s started"%selectInterfaceStr,"",wx.OK|wx.ICON_ERROR)
        monitorStarted.ShowModal()
        self.monitorInterface_button.Disable()      
        threading.Thread(target=self.camtableDetection,args=(selectInterfaceStr,)).start()
        threading.Thread(target=self.dhcpexhaustion,args=(selectInterfaceStr,)).start()

def camtableDetection(self,getInterface):
        global interface        
        interface = str(getInterface)
        THRESH=(254/4)
        START = 5
        def monitorPackets(p):
            if p.haslayer(IP):
                hwSrc = p.getlayer(Ether).src
                if hwSrc not in hwList:
                    hwList.append(hwSrc)
                delta = datetime.datetime.now() - start
                if((delta.seconds > START) and ((len(hwList)/delta.seconds) > THRESH)):
                    print "[*]- Detected CAM Table Attack."
                    #camAttackDetected = wx.MessageDialog(None,"Cam Attack Detected","",wx.ICON_ERROR)
                    #camAttackDetected.ShowModal()

    hwList = []
    start = datetime.datetime.now()
    sniff(iface=interface,prn=monitorPackets)


def dhcpexhaustion(self,getInterface):
    interface = str(getInterface)
    global reqCnt
    global ofrCnt
    reqCnt = 0
    ofrCnt = 0

    def monitorPackets(p):
        if p.haslayer(BOOTP):
            global reqCnt
            global ofrCnt
            opCode = p.getlayer(BOOTP).op
            if opCode == 1:
                reqCnt=reqCnt+1
            elif opCode == 2:
                ofrCnt=ofrCnt+1
            print "[*] - "+str(reqCnt)+" Requests, "+str(ofrCnt)+" Offers."
          sniff(iface=interface,prn=monitorPackets)

我想在点击按钮时停止线程,但不知道如何才能完成。

有自助技术,但我不知道如何在我的代码中应用它。

1 个答案:

答案 0 :(得分:1)

正如我在评论中所说:

  

如果[sniff]是一个你无法控制的函数(例如,来自C扩展模块)并且它永远循环,那么它必须有某种方法来取消它。也许它让你的回调返回一个特殊值,也许它正在调用一个控制函数,也许它正在关闭它正在处理的对象......不管它是什么,你必须这样做。

那么,为什么不阅读scapy.sniff的文档以了解如何取消它?

Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets

  count: number of packets to capture. 0 means infinity
  store: wether to store sniffed packets or discard them
    prn: function to apply to each packet. If something is returned,
         it is displayed. Ex:
         ex: prn = lambda x: x.summary()
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
opened_socket: provide an object ready to use .recv() on
stop_filter: python function applied to each packet to determine
             if we have to stop the capture after this packet
             ex: stop_filter = lambda x: x.haslayer(TCP)

所以,阻止它永远嗅探的方法是传递一个stop_filter函数,当你想要停止它时它会返回True。因此,您将检查stop标志。例如:

def __init__(self, whatever):
    self.stopflag = False
    self.stoplock = threading.Lock()
    # rest of your init

def stop(self):
    with self.stoplock:
        self.stopflag = True 

def stop_filter(self):
    with self.stoplock:
        return self.stopflag

def dhcpexhaustion(self, getInterface):
    # etc.
    sniff(iface=interface,prn=monitorPackets, stop_filter=self.stop_filter)

您可能希望在开始时存储两个Thread对象,因此您可以在停止时join对象,而不是直接泄漏它们直到您的程序退出。但除此之外,应该这样做。