Wireshark打印结果后崩溃,求忽略tshark包截断报错的解决方法
问题:实时处理PCAP文件时TShark崩溃(数据包截断)
通过CANoe生成.pcap格式日志文件,使用Python调用pyshark模块进行实时后处理时,打印结果后Wireshark出现崩溃。经排查,根因为实时处理过程中数据包被截断导致报错,已尝试异常处理但错误信息仍会输出,需要忽略该错误的解决方案。
相关代码
def Validate_IP_Assignment(Capture): try: capture_file = pyshark.FileCapture(Capture) host = None assigned_ip = None DHCP_Assigned = False vehicle_found = 0 for packet in capture_file: current_packet_number = int(packet.number) if (packet.highest_layer.upper() == 'DOIP' or packet.highest_layer.upper() == 'STCSIG'): try: if 'vin' in packet.doip.field_names: vehicle_found+=1 host = packet.ip.src #if host.startswith(('192.168.88')): #print('DHCP Assigned IP: ',host) except Exception as e: print(e) print("Exception 2",packet.highest_layer.upper()) pass canoe = CANoe() if(vehicle_found >= 3): print("printing the IP address") canoe.set_SysVar('wireshark', 'DHCP_server_state_start', 1) canoe.set_SysVar('wireshark', 'DHCP_Assigned_IP', host) if host.startswith('192.168.88'): canoe.set_SysVar('wireshark', 'IP_Type', 'DHCP') elif host.startswith('169.254'): #169.254.213.31 canoe.set_SysVar('wireshark', 'IP_Type', 'AutoIP') else: print("IP address is not assigned") canoe.set_SysVar('wireshark', 'DHCP_server_state_start', 0) capture_file.close() except pyshark.PySharkException as shark_exception: pass except pyshark.TSharkCrashException as tshark_exception: pass except Exception as e: pass
错误信息(中文翻译)
发生错误:TShark(进程ID 14148)似乎已崩溃(返回码:2)。 最后一条错误信息:tshark:文件"C:/Common_Configuration/wireshark106.pcap"似乎在数据包中间被截断。 尝试在调试模式下重新运行 [ capture_obj.set_debug() ] 或尝试更新tshark。 异常被忽略于:<function Capture.__del__ at 0x04202730> 回溯(最近的调用最后): 文件 "C:\Users\BCML2RIG\AppData\Roaming\Python\Python39\site-packages\pyshark\capture\capture.py", 第405行, 在 __del__中 self.close() 文件 "C:\Users\BCML2RIG\AppData\Roaming\Python\Python39\site-packages\pyshark\capture\capture.py", 第393行, 在 close中 self.eventloop.run_until_complete(self.close_async()) 文件 "C:\Program Files (x86)\Python39-32\lib\asyncio\base_events.py", 第647行, 在 run_until_complete中 return future.result() 文件 "C:\Users\BCML2RIG\AppData\Roaming\Python\Python39\site-packages\pyshark\capture\capture.py", 第397行, 在 close_async中 await self._cleanup_subprocess(process) 尝试在调试模式下重新运行 [ capture_obj.set_debug() ] 或尝试更新tshark。
解决方案
1. 配置pyshark忽略解析错误
创建FileCapture对象时,添加ignore_parsing_errors=True跳过解析失败的数据包,同时通过tshark_args传递参数让tshark进入安静模式,抑制错误输出:
capture_file = pyshark.FileCapture( Capture, ignore_parsing_errors=True, tshark_args=["-Q", "--no-duplicate-keys"] )
-Q:tshark安静模式,仅输出解析结果--no-duplicate-keys:避免字段重复引发的解析错误
2. 安全关闭捕获对象,避免__del__触发异常
错误的核心原因是捕获对象被垃圾回收时,__del__方法会再次执行close(),此时子进程已崩溃引发报错。需在finally块中安全关闭对象,并手动置为None阻止__del__触发:
finally: if capture_file: try: capture_file.close() except Exception: pass capture_file = None
3. 优化循环内异常处理
遍历数据包时,捕获所有解析异常并静默跳过错误包,避免单个数据包问题中断整个处理流程:
for packet in capture_file: try: current_packet_number = int(packet.number) if (packet.highest_layer.upper() == 'DOIP' or packet.highest_layer.upper() == 'STCSIG'): if 'vin' in packet.doip.field_names: vehicle_found += 1 host = packet.ip.src except Exception: continue
完整修改后的代码
def Validate_IP_Assignment(Capture): capture_file = None try: # 初始化捕获对象,配置忽略解析错误和tshark安静模式 capture_file = pyshark.FileCapture( Capture, ignore_parsing_errors=True, tshark_args=["-Q", "--no-duplicate-keys"] ) host = None vehicle_found = 0 for packet in capture_file: try: current_packet_number = int(packet.number) if (packet.highest_layer.upper() == 'DOIP' or packet.highest_layer.upper() == 'STCSIG'): if 'vin' in packet.doip.field_names: vehicle_found += 1 host = packet.ip.src except Exception: # 静默跳过解析失败的数据包 continue canoe = CANoe() if vehicle_found >= 3: print("打印IP地址") canoe.set_SysVar('wireshark', 'DHCP_server_state_start', 1) canoe.set_SysVar('wireshark', 'DHCP_Assigned_IP', host) if host.startswith('192.168.88'): canoe.set_SysVar('wireshark', 'IP_Type', 'DHCP') elif host.startswith('169.254'): canoe.set_SysVar('wireshark', 'IP_Type', 'AutoIP') else: print("未分配IP地址") canoe.set_SysVar('wireshark', 'DHCP_server_state_start', 0) except Exception: # 静默处理全局异常 pass finally: # 安全关闭捕获对象,避免__del__触发错误 if capture_file: try: capture_file.close() except Exception: pass capture_file = None
内容的提问来源于stack exchange,提问作者user123
相关产品推荐
相关产品推荐

