""" 网络工具类模块 提供网络同步插件所需的工具函数 """ import time import hashlib import zlib import base64 from typing import Dict, Any, List, Optional, Union import json import struct import threading class NetworkUtils: """ 网络工具类 提供网络同步插件所需的工具函数 """ def __init__(self, plugin): """ 初始化网络工具类 Args: plugin: 网络同步插件实例 """ self.plugin = plugin self.enabled = False self.initialized = False # 工具配置 self.utils_config = { "enable_caching": True, "cache_size": 1000, "enable_compression": True, "compression_level": 6, "enable_checksum": True, "max_retry_attempts": 3, "retry_delay": 1.0 } # 缓存管理 self.cache = {} self.cache_lock = threading.RLock() # 性能统计 self.utils_stats = { "cache_hits": 0, "cache_misses": 0, "compressions": 0, "decompressions": 0, "checksums_calculated": 0, "data_processed": 0, "functions_called": 0 } # 回调函数 self.utils_callbacks = { "cache_updated": [], "performance_alert": [] } # 时间戳记录 self.last_cache_cleanup = 0.0 self.last_utility_call = 0.0 print("✓ 网络工具类已创建") def initialize(self) -> bool: """ 初始化网络工具类 Returns: 是否初始化成功 """ try: self.initialized = True print("✓ 网络工具类初始化完成") return True except Exception as e: print(f"✗ 网络工具类初始化失败: {e}") import traceback traceback.print_exc() return False def enable(self) -> bool: """ 启用网络工具类 Returns: 是否启用成功 """ try: if not self.initialized: print("✗ 网络工具类未初始化") return False self.enabled = True print("✓ 网络工具类已启用") return True except Exception as e: print(f"✗ 网络工具类启用失败: {e}") import traceback traceback.print_exc() return False def disable(self): """禁用网络工具类""" try: self.enabled = False print("✓ 网络工具类已禁用") except Exception as e: print(f"✗ 网络工具类禁用失败: {e}") import traceback traceback.print_exc() def finalize(self): """清理网络工具类资源""" try: self.disable() self.cache.clear() self.utils_callbacks.clear() self.initialized = False print("✓ 网络工具类资源已清理") except Exception as e: print(f"✗ 网络工具类资源清理失败: {e}") import traceback traceback.print_exc() def update(self, dt: float): """ 更新网络工具类状态 Args: dt: 时间增量 """ try: if not self.enabled: return current_time = time.time() self.last_utility_call = current_time # 定期清理缓存 if current_time - self.last_cache_cleanup > 60.0: # 每分钟清理一次 self._cleanup_cache() self.last_cache_cleanup = current_time except Exception as e: print(f"✗ 网络工具类更新失败: {e}") import traceback traceback.print_exc() def _cleanup_cache(self): """清理缓存""" try: with self.cache_lock: if len(self.cache) > self.utils_config["cache_size"]: # 移除最旧的一半缓存项 items_to_remove = len(self.cache) - (self.utils_config["cache_size"] // 2) keys_to_remove = list(self.cache.keys())[:items_to_remove] for key in keys_to_remove: del self.cache[key] print(f"✓ 缓存已清理,移除了 {items_to_remove} 项") except Exception as e: print(f"✗ 缓存清理失败: {e}") def calculate_checksum(self, data: bytes) -> str: """ 计算数据校验和 Args: data: 要计算校验和的数据 Returns: 校验和字符串 """ try: self.utils_stats["functions_called"] += 1 self.utils_stats["checksums_calculated"] += 1 checksum = hashlib.md5(data).hexdigest() return checksum except Exception as e: print(f"✗ 校验和计算失败: {e}") return "" def compress_data(self, data: bytes) -> Optional[bytes]: """ 压缩数据 Args: data: 要压缩的数据 Returns: 压缩后的数据或None """ try: if not self.utils_config["enable_compression"]: return data self.utils_stats["functions_called"] += 1 self.utils_stats["compressions"] += 1 compressed_data = zlib.compress(data, self.utils_config["compression_level"]) self.utils_stats["data_processed"] += len(data) - len(compressed_data) return compressed_data except Exception as e: print(f"✗ 数据压缩失败: {e}") return None def decompress_data(self, data: bytes) -> Optional[bytes]: """ 解压缩数据 Args: data: 要解压缩的数据 Returns: 解压缩后的数据或None """ try: self.utils_stats["functions_called"] += 1 self.utils_stats["decompressions"] += 1 decompressed_data = zlib.decompress(data) return decompressed_data except Exception as e: print(f"✗ 数据解压缩失败: {e}") return None def encode_base64(self, data: bytes) -> str: """ Base64编码 Args: data: 要编码的数据 Returns: 编码后的字符串 """ try: self.utils_stats["functions_called"] += 1 encoded_data = base64.b64encode(data).decode('utf-8') return encoded_data except Exception as e: print(f"✗ Base64编码失败: {e}") return "" def decode_base64(self, data: str) -> Optional[bytes]: """ Base64解码 Args: data: 要解码的字符串 Returns: 解码后的数据或None """ try: self.utils_stats["functions_called"] += 1 decoded_data = base64.b64decode(data.encode('utf-8')) return decoded_data except Exception as e: print(f"✗ Base64解码失败: {e}") return None def generate_cache_key(self, data: Any) -> str: """ 生成缓存键 Args: data: 要生成键的数据 Returns: 缓存键字符串 """ try: self.utils_stats["functions_called"] += 1 # 生成数据的哈希值作为缓存键 data_str = str(data) cache_key = hashlib.sha256(data_str.encode('utf-8')).hexdigest() return cache_key except Exception as e: print(f"✗ 缓存键生成失败: {e}") return str(hash(data)) def cache_get(self, key: str) -> Optional[Any]: """ 从缓存获取数据 Args: key: 缓存键 Returns: 缓存数据或None """ try: if not self.utils_config["enable_caching"]: return None self.utils_stats["functions_called"] += 1 with self.cache_lock: if key in self.cache: self.utils_stats["cache_hits"] += 1 return self.cache[key]["data"] else: self.utils_stats["cache_misses"] += 1 return None except Exception as e: print(f"✗ 缓存获取失败: {e}") return None def cache_set(self, key: str, data: Any, ttl: float = 300.0) -> bool: """ 设置缓存数据 Args: key: 缓存键 data: 要缓存的数据 ttl: 生存时间(秒) Returns: 是否设置成功 """ try: if not self.utils_config["enable_caching"]: return False self.utils_stats["functions_called"] += 1 with self.cache_lock: self.cache[key] = { "data": data, "timestamp": time.time(), "ttl": ttl } # 触发缓存更新回调 self._trigger_utils_callback("cache_updated", { "key": key, "operation": "set" }) return True except Exception as e: print(f"✗ 缓存设置失败: {e}") return False def cache_delete(self, key: str) -> bool: """ 删除缓存数据 Args: key: 缓存键 Returns: 是否删除成功 """ try: self.utils_stats["functions_called"] += 1 with self.cache_lock: if key in self.cache: del self.cache[key] # 触发缓存更新回调 self._trigger_utils_callback("cache_updated", { "key": key, "operation": "delete" }) return True else: return False except Exception as e: print(f"✗ 缓存删除失败: {e}") return False def retry_operation(self, operation: callable, *args, **kwargs) -> Optional[Any]: """ 重试操作 Args: operation: 要重试的操作 *args: 操作参数 **kwargs: 操作关键字参数 Returns: 操作结果或None """ try: self.utils_stats["functions_called"] += 1 max_attempts = self.utils_config["max_retry_attempts"] delay = self.utils_config["retry_delay"] for attempt in range(max_attempts): try: result = operation(*args, **kwargs) return result except Exception as e: if attempt < max_attempts - 1: print(f"✗ 操作失败,{delay}秒后重试 ({attempt + 1}/{max_attempts}): {e}") time.sleep(delay) else: print(f"✗ 操作最终失败: {e}") return None except Exception as e: print(f"✗ 重试操作失败: {e}") return None def format_bytes(self, bytes_count: int) -> str: """ 格式化字节数 Args: bytes_count: 字节数 Returns: 格式化后的字符串 """ try: self.utils_stats["functions_called"] += 1 if bytes_count < 1024: return f"{bytes_count} B" elif bytes_count < 1024 * 1024: return f"{bytes_count / 1024:.2f} KB" elif bytes_count < 1024 * 1024 * 1024: return f"{bytes_count / (1024 * 1024):.2f} MB" else: return f"{bytes_count / (1024 * 1024 * 1024):.2f} GB" except Exception as e: print(f"✗ 字节格式化失败: {e}") return f"{bytes_count} B" def calculate_bandwidth(self, bytes_count: int, duration: float) -> float: """ 计算带宽 Args: bytes_count: 字节数 duration: 持续时间(秒) Returns: 带宽(B/s) """ try: self.utils_stats["functions_called"] += 1 if duration <= 0: return 0.0 bandwidth = bytes_count / duration return bandwidth except Exception as e: print(f"✗ 带宽计算失败: {e}") return 0.0 def get_local_ip(self) -> Optional[str]: """ 获取本地IP地址 Returns: 本地IP地址或None """ try: self.utils_stats["functions_called"] += 1 import socket # 获取本地IP地址 with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: # 连接到一个远程地址(不需要真实连接) s.connect(("8.8.8.8", 80)) local_ip = s.getsockname()[0] return local_ip except Exception as e: print(f"✗ 本地IP获取失败: {e}") return None def is_valid_port(self, port: int) -> bool: """ 检查端口是否有效 Args: port: 端口号 Returns: 端口是否有效 """ try: self.utils_stats["functions_called"] += 1 return 1 <= port <= 65535 except Exception as e: print(f"✗ 端口检查失败: {e}") return False def get_system_info(self) -> Dict[str, Any]: """ 获取系统信息 Returns: 系统信息字典 """ try: self.utils_stats["functions_called"] += 1 import platform import psutil system_info = { "platform": platform.system(), "platform_version": platform.version(), "architecture": platform.architecture()[0], "processor": platform.processor(), "cpu_count": psutil.cpu_count(), "memory_total": psutil.virtual_memory().total, "memory_available": psutil.virtual_memory().available } return system_info except Exception as e: print(f"✗ 系统信息获取失败: {e}") return {} def get_network_interfaces(self) -> List[Dict[str, Any]]: """ 获取网络接口信息 Returns: 网络接口信息列表 """ try: self.utils_stats["functions_called"] += 1 import psutil interfaces = [] net_if_addrs = psutil.net_if_addrs() for interface_name, interface_addresses in net_if_addrs.items(): interface_info = { "name": interface_name, "addresses": [] } for address in interface_addresses: interface_info["addresses"].append({ "family": str(address.family), "address": address.address, "netmask": address.netmask, "broadcast": address.broadcast }) interfaces.append(interface_info) return interfaces except Exception as e: print(f"✗ 网络接口信息获取失败: {e}") return [] def measure_latency(self, host: str, port: int, timeout: float = 5.0) -> Optional[float]: """ 测量网络延迟 Args: host: 主机地址 port: 端口号 timeout: 超时时间 Returns: 延迟时间(秒)或None """ try: self.utils_stats["functions_called"] += 1 import socket import time start_time = time.time() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.settimeout(timeout) result = sock.connect_ex((host, port)) if result == 0: end_time = time.time() latency = end_time - start_time return latency else: return None except Exception as e: print(f"✗ 延迟测量失败: {e}") return None def get_utils_stats(self) -> Dict[str, Any]: """ 获取工具统计信息 Returns: 工具统计字典 """ return self.utils_stats.copy() def reset_utils_stats(self): """重置工具统计信息""" try: self.utils_stats = { "cache_hits": 0, "cache_misses": 0, "compressions": 0, "decompressions": 0, "checksums_calculated": 0, "data_processed": 0, "functions_called": 0 } print("✓ 工具统计信息已重置") except Exception as e: print(f"✗ 工具统计信息重置失败: {e}") def set_utils_config(self, config: Dict[str, Any]) -> bool: """ 设置工具配置 Args: config: 工具配置字典 Returns: 是否设置成功 """ try: self.utils_config.update(config) print(f"✓ 工具配置已更新: {self.utils_config}") return True except Exception as e: print(f"✗ 工具配置设置失败: {e}") return False def get_utils_config(self) -> Dict[str, Any]: """ 获取工具配置 Returns: 工具配置字典 """ return self.utils_config.copy() def _trigger_utils_callback(self, callback_type: str, data: Dict[str, Any]): """ 触发工具回调 Args: callback_type: 回调类型 data: 回调数据 """ try: if callback_type in self.utils_callbacks: for callback in self.utils_callbacks[callback_type]: try: callback(data) except Exception as e: print(f"✗ 工具回调执行失败: {e}") except Exception as e: print(f"✗ 工具回调触发失败: {e}") def register_utils_callback(self, callback_type: str, callback: callable): """ 注册工具回调 Args: callback_type: 回调类型 callback: 回调函数 """ try: if callback_type in self.utils_callbacks: self.utils_callbacks[callback_type].append(callback) print(f"✓ 工具回调已注册: {callback_type}") else: print(f"✗ 无效的回调类型: {callback_type}") except Exception as e: print(f"✗ 工具回调注册失败: {e}") def unregister_utils_callback(self, callback_type: str, callback: callable): """ 注销工具回调 Args: callback_type: 回调类型 callback: 回调函数 """ try: if callback_type in self.utils_callbacks: if callback in self.utils_callbacks[callback_type]: self.utils_callbacks[callback_type].remove(callback) print(f"✓ 工具回调已注销: {callback_type}") except Exception as e: print(f"✗ 工具回调注销失败: {e}")