python psutil 实现了网卡的流量统计功能,用tabulate生成表格,需要安装psutil,tabulate,wcwidth
import datetime
import os
import psutil
from tabulate import tabulate
import time
class NetworkTrafficMonitor:
"""
A network traffic monitoring tool.
"""
def __init__(self):
print("Network Traffic Monitor started...")
self.clear_screen()
def clear_screen(self):
"""Clear the console screen."""
os.system('cls' if os.name == 'nt' else 'clear')
def get_network_bytes(self):
"""
Get current network I/O counters per interface.
:return: Current network I/O counters per interface.
"""
return psutil.net_io_counters(pernic=True)
@staticmethod
def format_size(size, suffix='B'):
"""
Format size in a human-readable way.
:param size: Size in bytes.
:param suffix: Suffix for the unit (default 'B').
:return: Formatted size string.
"""
for unit in ['', 'Ki', 'Mi', 'Gi']:
if abs(size) < 1024.0:
return f"{size:.2f}{unit}{suffix}"
size /= 1024.0
return f"{size:.2f}Ti{suffix}"
def format_speed(self, speed):
"""
Format speed in a human-readable way.
:param speed: Speed in bytes per second.
:return: Formatted speed string.
"""
return self.format_size(speed, '/s')
def cmd_mode(self):
"""
Command-line mode monitor.
"""
last_bytes = self.get_network_bytes()
total_bytes = {iface: {'sent': sent, 'recv': recv} for iface, (sent, recv) in self._extract_bytes(last_bytes).items()}
while True:
time.sleep(1)
current_bytes = self.get_network_bytes()
data = []
for interface, (sent, recv) in self._extract_bytes(current_bytes).items():
last_sent, last_recv = total_bytes[interface]['sent'], total_bytes[interface]['recv']
speed_sent, speed_recv = sent - last_sent, recv - last_recv
total_sent, total_recv = sent - last_bytes[interface].bytes_sent, recv - last_bytes[interface].bytes_recv
data.append([
interface,
self.format_speed(speed_sent),
self.format_speed(speed_recv),
self.format_size(total_sent),
self.format_size(total_recv)
])
headers = ["Interface", "Upload Speed", "Download Speed", "Total Upload", "Total Download"]
table = tabulate(data, headers=headers, tablefmt="fancy_grid")
self.clear_screen()
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"{'_' * 79}\n"
f"|{' Network Traffic Monitor '.center(75)}|\n"
f"|{'Current Time:':<24}{now:<24}|\n"
f"|{'-' * 75}|\n"
f"|{'Author:':<69}|\n"
f"{'_' * 79}\n\n"
f"{table}\n")
if input("Press 'c' to continue or 'q' to quit: ").lower() == 'q':
break
last_bytes = current_bytes
@staticmethod
def _extract_bytes(io_counters):
"""
Extract bytes sent and received from IO counters.
:param io_counters: IO counters per interface.
:return: Dictionary with interfaces and their bytes sent and received.
"""
return {
interface: (io.bytes_sent, io.bytes_recv)
for interface, io in io_counters.items()
}
if __name__ == '__main__':
monitor = NetworkTrafficMonitor()
monitor.cmd_mode()