2014-03-19 69 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) 不會拋出錯誤,但可能是它沒有顯示值的原因?再次感謝您的建議:) –