-1

如何通过单击 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)

我正在考虑单击按钮时停止线程,但不知道如何完成。

有 self.abort 技术,但我不确定如何在我的代码中应用它。

4

1 回答 1

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在停止时存储它们,而不是在程序退出之前泄漏它们。但否则,这应该这样做。

于 2013-10-06T02:59:43.573 回答