2014-03-19 67 views
0

感谢您花时间看看这个!Python:线程ARP ping的奇怪输出

我遇到的问题是我的线程ARP脚本的输出。我试图实现的是将每个活动主机输出的IP地址,MAC地址和NIC供应商都命令提示符。

我有一个老的ARP脚本没有线程,这需要大约90秒,并打印我的理想输出。

下面是我的新脚本,基于上述脚本,使用线程。不幸的是,我不知道为什么输出中没有显示值。如果有人能帮助我,我将非常感激!

提前致谢!

def arp2(ip): 

    # An ARP scanner for the network. 
    ips = [] 

    global ans, unans 
    ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip), timeout=2, verbose=0) 

    for snd, rcv in ans: 
    #Assign MAC address and IP address to variables mac and ipaddr 

     mac = rcv.sprintf(r"%Ether.src%") 
     ipaddr = rcv.sprintf(r"%ARP.psrc%") 

     #Get NIC vendor code from MAC address 
     niccode = mac[:8] 
     niccode = niccode.upper() 

     print ips 
     ips.append("end") 

     #ARPips file amendments 
     with open('C:\Python26\ARPips.prn', 'w+') as f: 
      f.write("\n".join(map(lambda x: str(x), ips)) + "\n") 

     #String lookup for NIC vendors. DO NOT CHANGE 'r' TO ANY OTHER VALUE. 
     with open('C:\Users\TomVB\Desktop\OID2.prn', 'r') as file: 
      for line in file: 
       if niccode in file: 
        return mac, ipaddr, line[8:] 




def main(): 

    print "Discovering..." 
    print "" 
    print "MAC Address \t \t IP Address \t NIC Vendor" 


    pool = Pool(processes=12) 

    Subnetlist = [] 

    for i in range(255): 
     Subnetlist.append(str(IPInt+str(i))) 

    global ARPresults 
    ARPresults = pool.map(arp2, Subnetlist) 

    pool.close() 
    pool.join() 


    print "\n".join(ARPresults) 

if __name__ == '__main__': 
    main() 

这个剧本给了我下面的输出:

Mac Address IP address  NIC Vendor 

[][] 

[] 

[] 

[] 
[] 
[][] 
[] 

[] 

等这样的周边的200线。

+0

[重读我的回答你刚才的问题。这个问题是类似的](http://stackoverflow.com/q/22330003/4279) – jfs

+0

嘿@ J.F.Sebastian,感谢您看到这个,我想这个时候我写了这个脚本。你知道为什么它没有打印,即使mac和ipaddr被返回,地图选择它们吗?我觉得我错过了一些非常明显的东西): –

+0

上一个问题中的第一个问题:'ping()'不会返回任何内容,但是您正尝试打印其结果。 'arp2()'返回什么? – jfs

回答

0

首先,它看起来像你使用多处理而不是线程。这两个人的表现完全不同,我建议你看看。无论如何,对于手头的问题,原因在别处。

arp2方法是并行执行的。我在该方法中看到两个问题:

print "%s \t %s \t %s" % (mac, ipaddr, line[8:]) 

此语句打印到标准输出。在我们的代码中,它可能会同时执行多达12个进程。 Python不保证print语句是原子的。当下一个进程写入他的行时,一个进程写了​​一半的行可能会发生。总之,你会在输出中混乱不堪。

这同样适用于

with open('C:\Python26\ARPips.prn', 'w+') as f: 
    f.write("\n".join(map(lambda x: str(x), ips)) + "\n") 

同样没有保证,该进程不会对每个人的脚趾一步。文件内容可能会被冒名顶替。

最简单的解决方案是不要在arp2方法中执行任何文件或控制台输出。而是返回结果。 pool.map将以安全的方式为您收集这些结果。它的行为与常规的map函数相似。然后你可以将它们输出到文件和控制台。

如果你想输出,而扫描运行,你必须处理(例如用multiprocessing.Lock同步,以便只有一个进程的同时不断书写/印刷

另外:。

  • 把一个“R”在字符串与windows风格的路径的前:x = r'C:\Users\TomVB\Desktop\OID2.prn'反斜杠用于在Python逸出

  • 负荷C:\Users\TomVB\Desktop\OID2.prn含量为012。。它会更快。

  • map(lambda x: str(x), ips)等于map(str, ips)

+0

嗨@Stefan非常感谢您的回复!我真的很感谢你的时间和我一起看这个。 至于你的答案,我改变了这种说法: 打印 “%S \ t%S \ T%的” %(MAC,IP地址,行[8:]) 到这一点: 回报MAC, ipaddr,line [8:] 但是输出通常会是,例如: [5] [3] [1] [2] [4] [1] [5] [2] [4] [5] 输出仍是与此类似: [] [] [] [] [] [] []等。 任何想法为什么这可能会发生? –

+0

请显示您使用的实际代码。您所描述的内容与您的代码不符。如果你唯一的改变是返回一个元组,那么'ARPresults'将是一个元组列表。 'print'\ n“.join(ARPresults)'会引发错误。还请清理未使用的代码,如'hostID + = 1'。 – Stefan

+0

Hi @Stefan Hi @Stefan,我做了一些修改,声明: print“\ n”.join(ARPresults) 不会抛出错误,但可能是它没有显示值的原因?再次感谢您的建议:) –