簡體   English   中英

在多線程Python程序中捕獲數據包的有效方法

[英]Efficient way to capture packets in multithreading Python program

我正在使用Python實現嗅探器。 我需要所有數據包詳細信息(VLAN等),所以我使用的是RAW套接字。 我所有的以太網接口上都有多個嗅探器充當惡魔,因此每個嗅探器都位於不同的線程中。

除了將數據包添加到的全局變量之外,還有什么更好的方法可以在主線程中獲得結果(如下面的代碼所示)?

我嘗試了Queue,但是除了增加復雜性之外,沒有看到任何其他好處。

import socket, threading

def ReceivePackets():
    soc = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))  
    while 1:
        packet = soc.recv(2000)  
        buffer.append(packet)

def ReadSniffer():
    result = list(buffer) 
    #Clear buffer to start sniffing from scratch after reading
    del buffer[:]
return result

我在程序開始時在所有以太網接口上啟動嗅探器,並在需要數據時讀取相應的全局緩沖區。

buffer = []
t = threading.Thread(target = ReceivePackets)
t.daemon = True
t.start()
...
packets = ReadSniffer()

使用套接字時,總是得到不一致的結果,因為我有各種不同大小的數據包。 一個套接字可以捕獲我幾次發送的所有數據包,但最終會丟失一些數據包。

我移到了libcap庫的pcapy接口,而不是原始套接字,它可以完美且非常可靠地工作。

我將Sniffer類實現為threading.Thread的子類,因此它在單獨的線程中啟動。 實現是這樣的:

class Sniffer(threading.Thread):

    def __init__(self, port):      
        ...
        threading.Thread.__init__(self)
        #Packets will be stored here
        self.result = []
        #Not worry about closing the sniffer thread
        self.daemon = True    

    #Invoked when I start my thread
    def run(self):      
        max_bytes = 16000
        #Important to capture broken packets as I need them
        promiscuous = True
        read_timeout = 100
        pc = pcapy.open_live(str(self.port), max_bytes, promiscuous, read_timeout)
        pc.loop(-1, self.recv_pkts)

    #Do when the packet arrives
    def recv_pkts(self, hdr, packet):
        packetHex = binascii.hexlify(packet)
        self.result.append(packetHex)
        return self.result

要與主程序並行啟動嗅探器線程:

 sniffer1 = Sniffer(eth1)
 #Start separate thread
 sniffer1.start()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM