将Scapy输出打印到wxPython文本控制器

时间:2013-03-25 16:22:04

标签: python wxpython scapy

感谢您花时间看我的问题。

我正在学习wxPython的绳索,我想把一个工作程序输出到终端并给它一个整容。使用Scapy,我正在嗅探我的探测请求/探测响应的无线接口,它按预期工作。但是,我希望不是输出到终端窗口,而是将其输出到新GUI中的StaticText(tc2)帧。

现在我一直在使用教程来创建我的GUI,但是,当前代码在加载我的GUI之前仍然将Scapy输出到终端,因为嗅探功能一直运行直到它被用户杀死,因此从未真正加载GUI。我已经尝试将嗅探功能放在wx.StaticText行中,但没有把它打印到那里的乐趣。

我的Scapy程序和GUI程序都可以自行运行,但它们不能同时工作。我的目标是将返回值显示在StaticText框中。以下是与我的问题相关的一小部分代码。

tc2 = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100), style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

btn1 = wx.Button(panel, label='Sniff', size=(70, 30))
self.Bind(wx.EVT_BUTTON, self.OnSniff, btn1)

redir=RedirectText(tc2)
sys.stdout=redir

def OnSniff(self,e):
sniff(iface="mon0",prn=packets,store=0)

def packets(p):
if p.haslayer(Dot11ProbeReq):
    dstmac=p.addr1
    mac=p.addr2
    if p.info == "":
    ssid="BROADCAST"
    else:
    ssid=p.info

    print "%s is probing %s %s" % (mac,dstmac,ssid)

if p.haslayer(Dot11ProbeResp):
    dstmac=p.addr1
    bssid=p.addr2
        ssid=p.info
        print "%s (%s) Probe Response to %s" % (ssid,bssid,dstmac)

wx.Yield()

1 个答案:

答案 0 :(得分:1)

在加载wxPython应用程序之前,您不想开始嗅探。所以你要么想要在按钮或菜单事件处理程序中启动嗅探,要么你可以使用wx.CallLater在应用程序加载后开始执行,方法是将callLater命令放在wx代码的init的末尾。

当我重定向ping命令(以及其他内容)时,我做了类似的事情。你可以看一下关于这个主题的tutorial。如果您需要更多有关重定向标准输出的背景信息,请参阅here

这个问题的基本要点在我的另一个答案中有所提及:Redirect command prompt output to a python generated window

基本上你想要使用以下内容重定向文本:

class RedirectText:
    def __init__(self,aWxTextCtrl):
        self.out=aWxTextCtrl

    def write(self,string):
        self.out.WriteText(string)

然后在我的ping示例中,我执行了以下操作:

def pingIP(self, ip):
    proc = subprocess.Popen("ping %s" % ip, shell=True, 
                            stdout=subprocess.PIPE) 
    print
    while True:
        line = proc.stdout.readline()                        
        wx.Yield()
        if line.strip() == "":
            pass
        else:
            print line.strip()
        if not line: break
    proc.wait()

要看的主要内容是子进程调用中的stdout参数,而wx.Yield()也很重要。 Yield允许文本被“打印”(即重定向)到stdout。没有它,文本将在命令完成后才会显示。我希望这一切都有道理。

如果你需要在一个单独的线程中运行它,这里有几个链接: