EG/plugins/user/network_sync/utils/network_utils.py
2025-10-30 11:46:41 +08:00

730 lines
21 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
网络工具类模块
提供网络同步插件所需的工具函数
"""
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}")