【问题标题】:queue.get() returns only one itemqueue.get() 只返回一项
【发布时间】:2015-12-09 13:31:38
【问题描述】:

我正在构建一个小嗅探器来接收网络中设备的答案。我宁愿通过实现 Scapys Packet 类的answers() 方法来解决这个问题,但这并没有按预期工作。我试图绕过这个,首先创建一个嗅探线程,然后向设备发送一个数据包并等待答案。

import threading
from scapy.all import sniff
class SnifferThread(threading.Thread):

    """ Thread that sniffs for incoming packets
    """

    def __init__(self, queue, timeout=1, checkFunction=None, filter=None):
        """ Initialization method """
        if queue is None:
            raise Exception, "queue must not be None"

        self.q = queue
        self.filter = filter
        self.timeout = timeout
        self.checkFunction = checkFunction

        threading.Thread.__init__(self)


    def putInQueue(self, packet):
        """ Checks packet and puts it into the queue if it matches """
        if self.checkFunction:
            if self.checkFunction(packet):
                self.q.put(packet)
                print "put"
        else:
            self.q.put(packet)


    def run(self):
        """ Executes the sniffing """
        sniff(
            timeout=self.timeout,
            filter=self.filter,
            prn=lambda pkt: self.putInQueue(pkt)
        )

def has_IAm(packet):
    """ Checks whether the packet contains an IAm """
    if packet.haslayer(APDU):
        if (packet[APDU].serviceChoice\
                == BACNetAPDUUnconfirmedServiceChoice.I_AM):
            print "has I_AM"
            return True


def discoverDevices():
    """ Sends WhoIs packet and prints answers """

    bindBACNetLayers()

    myQ = Queue.Queue()

    sniffer = SnifferThread(
        queue=myQ,
        checkFunction=has_IAm,
        filter=FILTER_BACNET
    )
    sniffer.start()

    sendp(
        getBACNetWhoIsPacket(
            "192.168.1.1",
            "192.168.1.255"
        ),
        verbose=False
    )

    while sniffer.isAlive():
        print "still alive"
    print myQ.qsize()
    answers = PacketList()
    answers.append(myQ.get())

    answers.show()

discoverDevices()

执行它时,我可以在 Wireshark 中看到两个设备通过发送 I_AM 数据包来响应。我还可以看到队列中有两个项目,因为最后print myQ.qsize() 打印2。所以我希望myQ.get() 返回两个数据包对象,然后在执行answers.show() 时显示在终端中,但不知何故只显示一个数据包——第一个被接收的数据包。我是否错误地使用了myQ.get()


我就这样解决了

while sniffer.isAlive():
    pass
answers = PacketList()
for _ in range(myQ.qsize()):
    answers.append(myQ.get())

【问题讨论】:

    标签: python queue scapy python-multithreading


    【解决方案1】:

    get 将始终返回单个项目,正如 documentation 所说:

    从队列中删除并返回一个项目。

    您应该反复调用get,直到队列为空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多