1

我一整天都在等待一个循环退出而没有希望!我知道 python 在性能方面效率不高,因此我非常感谢任何针对我的问题的加速建议。

我使用wireshark 捕获了大量数据包(大约500,000 个)并将它们保存到.pcap 文件中。之后,我使用 Scapy rdpcap() 函数从保存的文件中读取数据包,然后循环访问每个数据包以提取源 IP 地址。我的代码如下:

from scaly.all import *

srcList =[]
Packets = rdpcap("pcapfile")

for pkt in Packets:
    src = Packets[Packets.index(pkt)][1].src
    srcList.append(src)

注意:我做了一些挖掘,发现 Cython 用于加速嵌套循环,但老实说,我不知道如何在我的情况下使用它。任何见解都会很棒

4

3 回答 3

6

如果我没有误解您的意图,您可以简化代码,这也应该加快速度:

from scaly.all import *

Packets = rdpcap("pcapfile")
srcList = [pkt[1].src for pkt in Packets]

这个解决方案和你的解决方案之间的区别可以用一个简单的例子来说明。如您所见,第二个功能快了 10 倍以上。

In [1]: lst = range(100)

In [2]: def f1(lst):
   ...:     out = []
   ...:     for item in lst:
   ...:         out.append(lst[lst.index(item)])
   ...:     return out

In [3]: def f2(lst):
   ...:     return [item for item in lst]

In [4]: %timeit f1(lst)
1000 loops, best of 3: 221 us per loop

In [5]: %timeit f2(lst)
100000 loops, best of 3: 9.61 us per loop
于 2013-01-22T10:47:11.540 回答
4

我怀疑问题出在网上,src = Packets[Packets.index(pkt)][1].src因为循环是O(n)并且列表搜索正在O(n)发生O(n**2)

也许以下内容也可以:

from scaly.all import *

srcList =[]
Packets = rdpcap("pcapfile")

for pkt in Packets:
    src = pkt[1].src
    srcList.append(src)

或者

from scaly.all import *

Packets = rdpcap("pcapfile")
srcList = [pkt[1].src for pkt in Packets]
于 2013-01-22T10:47:30.520 回答
0

如果您想要的只是 IP 源,请告诉 scapy 在 IP 层之后忽略解析任何内容:

IP.payload_guess = []

把它放在调用 to 之前rdpcap。Scapy 花费大量时间遍历每一层,解析和提取它可以找到的所有内容。这是大部分时间用于读取数据包的地方。

另外,考虑更改rdpcapfor PcapReader,它不会加载整个文件。这不一定会加快速度,但会减少内存占用。

于 2020-05-05T14:50:54.237 回答