繁体   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