"""
网络监测v2.0,改进为使用多进程并发监测多个IP或域名,更加高效
兼容WINXP系统
同时检查本地到baidu.com或qq.com等的通讯情况并附至邮件,可以更客观地了解本地网络情况
linxingyi
20160305
"""
import os, time,subprocess, smtplib, datetime, platform
from multiprocessing import Pool
from email.header import Header
from email.mime.text import MIMEText
IP = ["www.baidu.com","www.qq.com","www.sina.com"]
#保存ping命令执行结果的临时文件列表,大小与IP列表一致
f = ["d:/ping11.txt","d:/ping12.txt","d:/ping13.txt"]
#保存网络状态的列表,大小与IP列表一致
status = ["","",""]
#发邮件的定义
from_addr = '' #发件人的邮箱地址
to_addr = ['####@qq.com'] #收件人邮箱地址,用,来分隔
smtp_server = 'smtp.qq.com'
password = '############'
mailtext = ["","",""]
#监测IP通讯情况,输出到临时文件
def ping(name,IP,file):
print('Run task %s (%s)...' % (name, os.getpid()))
subprocess.call(["ping",IP,"-n","20"],shell=True,stdout=open(file,"wb"))
#根据临时文件内容判断网络状态
def netStatus(file,IP):
#判断是否为WINxp
if platform.version().split(".")[0] == "5":
with open(file,"r") as f:
a = f.readlines()
if len(a) != 1:
#IP = a[2].split()[1]
count = int(a[-6].split()[-3])
value = int(a[-2].split()[-1][:-2])
log(IP+"丢包个数为 %s" %count)
log(IP+"平均ping值为 %s" %value)
#判断为网络差的条件
if count > 5 or value > 100:
status = "bad"
return status,a[-6:]
else:
status = "good"
return status,a[-6:]
else:
#IP = a[0].split()[1]
status = "请求找不到主机"
log(IP+status)
return status,a[0]
else:
with open(file,"r") as f:
a = f.readlines()
if len(a) != 1:
#IP = a[1].split()[2]
count = int(a[-3].split()[-3])
value = int(a[-1].split()[-1][:-2])
log(IP+"丢包个数为 %s" %count)
log(IP+"平均ping值为 %s" %value)
#判断为网络差的条件
if count > 5 or value > 100:
status = "bad"
return status,a[-3:]
else:
status = "good"
return status,a[-3:]
else:
#IP = a[0].split()[2]
status = "请求找不到主机"
log(IP+status)
return status,a[0]
#输出日志并在控制台打印
def log(str):
with open('D:/dnslog.txt','a') as f:
f.write(str+"\n")
print(str)
#发送邮件
def faemail(msgtext):
msg = MIMEText(msgtext, 'plain', 'utf-8')
msg['From'] = from_addr
msg['To'] = ', '.join(to_addr)
msg['Subject'] = Header('线路预警', 'utf-8').encode()
server = smtplib.SMTP_SSL(smtp_server, 465)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, to_addr, msg.as_string())
server.quit()
if __name__=='__main__':
#持续监测
while True:
print('Parent process %s.' % os.getpid())
start = time.time()
log(str(datetime.datetime.now()))
#创建和IP列表大小相同的进程池,调用ping方法
p = Pool(3)
for i in range(3):
p.apply_async(ping,args=(i,IP[i],f[i],))
print('Waiting for all subprocesses done...')
p.close()
p.join()
#获取网络状态和邮件文本
for i in range(3):
status[i],s = netStatus(f[i],IP[i])
mailtext[i] = IP[i] + "".join(s)
for s in status:
print(s)
print("".join(mailtext))
#此处选择为第一个IP网络情况不佳时发送邮件
try:
if status[0] == "bad":
faemail("".join(mailtext))
except Exception as e:
log(e,":邮件发送失败")
end = time.time()
print('runs %0.2f seconds.' % (end - start))
log("------------------------------------------------------------------")
#每次监测的时间间隔
time.sleep(10)