最近做了一个局域网文件传输系统,需要网络流量监视,市面上的安全软件具有此功能,但是界面太小不方便查看,因此我设计了这个网络流量监视器。
程序界面:
首先,查阅网络资料,我们可以用psutil库获取计算机的网络端口信息,具体用法是
psutil.net_io_counters(pernic=True)
调用这个函数,我们可以看到一大串信息
为了确定这个函数的返回的对象类型,我们不妨调用一下 type()
可以看到这是一个字典类型的数据,其数据结构为{“端口名”:某种对象,....}
我们可以用“.”运算符获取其属性的值,例如
在这个程序中,我们只需要提取其中 bytes_sent和bytes_recv,就可以提取到单个端口的当前收发字节数,对于多个端口,用一个for循环即可;
def get_network_bytes():
"""
获取当前端口收发字节数
:return:当前各个端口的收发字节数
"""
network_io = psutil.net_io_counters(pernic=True)
bytes_now = {}
for interface, io in network_io.items():
bytes_now[interface] = {'上传字节数': io.bytes_sent, '下载字节数': io.bytes_recv}
return bytes_now
获取了当前的收发字节数,结合上一次的收发字节数,就可以计算当前的网络速率,用当前的收发字节数减去第一次的收发字节数,就可以得到总共的流量,方便表示,我们可以设计两个格式化网络速率的函数:
def format_speed(speed):
"""
获取直观的网速格式
:param speed: 网速 Byte/s
:return: 格式化网速
"""
if speed < 1024:
return f"{speed} B/s"
elif speed < 1048576:
return f"{speed / 1024:.2f} KB/s"
else:
return f"{speed / 1048576:.2f} MB/s"
def format_netdata(da):
"""
获取直观的流量格式
:param da: 字节数
:return: 格式化字节数
"""
if da < 1024:
return f"{da} B"
elif da < 1048576:
return f"{da / 1024:.2f} KB"
elif da < 1073741824:
return f"{da / 1048576:.2f} MB"
else:
return f"{da / 1073741824:.2f} GB"
将以上的代码进行封装,加上亿点点细节,得到程序的源代码:
import datetime
import os
import psutil
from tabulate import tabulate
import time
class NetworkTrafficMonitor:
"""
网络流量监视工具
"""
def __init__(self):
print("网络流量监视器启动..........")
def get_network_bytes(self):
"""
获取当前端口收发字节数
:return:当前各个端口的收发字节数
"""
network_io = psutil.net_io_counters(pernic=True)
bytes_now = {}
for interface, io in network_io.items():
bytes_now[interface] = {'上传字节数': io.bytes_sent, '下载字节数': io.bytes_recv}
return bytes_now
def format_speed(self, speed):
"""
获取直观的网速格式
:param speed: 网速 Byte/s
:return: 格式化网速
"""
if speed < 1024:
return f"{speed} B/s"
elif speed < 1048576:
return f"{speed / 1024:.2f} KB/s"
else:
return f"{speed / 1048576:.2f} MB/s"
def format_netdata(self, da):
"""
获取直观的流量格式
:param da: 字节数
:return: 格式化字节数
"""
if da < 1024:
return f"{da} B"
elif da < 1048576:
return f"{da / 1024:.2f} KB"
elif da < 1073741824:
return f"{da / 1048576:.2f} MB"
else:
return f"{da / 1073741824:.2f} GB"
def cmd_mode(self):
"""
cmd模式下的监视器
:return:
"""
last_speed = self.get_network_bytes() # 获取一次当前收发字节数,用于计算网速
raw_speed = self.get_network_bytes() # 获取一次当前收发字节数,用于累积计算流量
#创建初始字节数字典用于运算
raw = {}
for interface, bytes1 in raw_speed.items():
raw[interface] = [bytes1['上传字节数'], bytes1['下载字节数']]
while True:
time.sleep(1) # 等待一秒
network_speeds = self.get_network_bytes()#获取一次当前收发字节数
# 创建上一次字节数字典用于运算
last = {}
for interface, bytes1 in last_speed.items():
last[interface] = [bytes1['上传字节数'], bytes1['下载字节数']]
data = []#用于显示数据的列表
for interface, bytes1 in network_speeds.items():
data.append([interface, self.format_speed(bytes1['上传字节数'] - last[interface][0]),
self.format_speed(bytes1['下载字节数'] - last[interface][1]),
self.format_netdata(bytes1['上传字节数'] - raw[interface][0]),
self.format_netdata(bytes1['下载字节数'] - raw[interface][1])])
#用tabulate库中tabulate函数生成表格对象
headers = ["接口", "上传速率", "下载速率", "累积上传", "累积下载"]
table = tabulate(data, headers, tablefmt="grid")
# 打印输出表格
os.system("cls")
print(f"_____________________________________________________________________________________\n"
f"| |\n"
f"| 正在监视网络连接... 当前时间:{str(datetime.datetime.now())[:-3]} |\n"
f"| 作者:Y.d|")
print(table)
# 更新数据
last_speed = network_speeds
if __name__ == '__main__':
monitor = NetworkTrafficMonitor()
monitor.cmd_mode()
画一个小图标:
用pyinstaller打包:
pyinstaller -F -i 1.bmp 网络流量监视器.py
实际效果: