为什么 PyShark 会超时继续 LiveCapture?

Why does PyShark continue a LiveCapture with a timeout?

我的意思是,我想 PyShark 会继续监听。我的代码是(在 class 内):

 def Capture(self, incoming):

    capture = pyshark.LiveCapture()
    capture.sniff(timeout=int(incoming))
    print('TIMEOUT: ' + str(int(incoming)))
    print(capture)

    print("Len" + str(len(capture)))
    pktList = [] 
    count=0
    for pkt in capture:
        count=count+1
        pktList.append([int(pkt.layers[1].version), pkt.layers[2].layer_name, pkt.length])
        print(f"Saved packet #{count}")
        print(pktList)
    print("Job is done.")

输出显示,尽管在 2 秒超时后捕获由单个数据包组成,程序仍以某种方式继续读取一些数据。输出:

TIMEOUT: 2
<LiveCapture (0 packets)>
Len 0
Saved packet #1
[[4, 'tcp', '108']]
Saved packet #2
[[4, 'tcp', '108'], [4, 'tcp', '112']]
Saved packet #3
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108']]
Saved packet #4
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108'], [4, 'tcp', '112']]
Saved packet #5
[[4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '108'], [4, 'tcp', '112'], [4, 'tcp', '54']]

.......

我该如何解决?

我尝试使用您的代码,但无法使其正常工作。

我知道 capture.sniff(timeout=x) 的工作方式存在一些已知问题,所以我整理了一些使用 apply_on_packets 超时.

import pyshark
import asyncio

packet_list = []


def process_packets(packet):
    global packet_list
    try:
        packet_version = packet.layers[1].version
        layer_name = packet.layers[2].layer_name
        packet_list.append(f'{packet_version}, {layer_name}, {packet.length}')
    except AttributeError:
        pass


def capture_packets(timeout):
    capture = pyshark.LiveCapture(interface='en0')
    try:
      capture.apply_on_packets(process_packets, timeout=timeout)
    except asyncio.TimeoutError:
        pass
    finally:
        global packet_list
        for item in packet_list:
            print(item)


capture_packets(2)

我决定重新编写您的代码。下面的代码适用于 capture.sniff(timeout=x).

import pyshark

packet_list = []

def capture_packets(timeout):
    global packet_list

    capture = pyshark.LiveCapture(interface='en0')
    capture.sniff(timeout=timeout)
    packets = [pkt for pkt in capture._packets]
    capture.close()

    try:
        for packet in packets:
            packet_version = packet.layers[1].version
            layer_name = packet.layers[2].layer_name
            packet_list.append(f'{packet_version}, {layer_name}, {packet.length}')
    except AttributeError:
        pass
    finally:
        return packet_list


packets = capture_packets(2)
print(packets)
['4, tcp, 54', '6, icmpv6, 86', '6, icmpv6, 78', '4, tcp, 66']

我会回答您对上述代码示例的任何问题。

----------------------------------------
My system information
----------------------------------------
Platform:    macOS
Python:      3.8.0
Pyshark:     0.4.3
----------------------------------------