基于Python的Web版网络连通性测试工具
# 文件名: ping.py
# 作者: wanghongwei
# 日期: 2025年7月16日
# 版本: 1.0
# 描述: 基于Python的Web版网络连通性测试工具,通过浏览器界面执行Ping命令并展示结果
# 使用方式: 直接运行脚本,然后在浏览器访问 http://localhost:8000,输入目标域名或IP地址进行Ping测试
import http.server
import socketserver
import subprocess
import urllib.parse
import re
import sys
import locale
import platform
PORT = 8000
class PingHandler(http.server.BaseHTTPRequestHandler):
def _set_headers(self, status=200):
self.send_response(status)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
def _get_system_encoding(self):
"""获取系统控制台编码"""
try:
# Windows系统通常使用GBK编码
if platform.system() == 'Windows':
return 'gbk'
# Linux/Mac系统使用UTF-8
return 'utf-8'
except:
return 'utf-8'
def do_GET(self):
if self.path == '/':
self._set_headers()
# 返回包含ping表单的HTML页面
html = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网络连通性测试</title>
<style>
body { font-family: "Microsoft YaHei", "Segoe UI", sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f0f8ff; }
.container { background-color: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 15px rgba(0,0,0,0.1); }
h1 { color: #2c3e50; text-align: center; margin-bottom: 25px; }
form { display: flex; margin: 25px 0; }
input[type="text"] { flex-grow: 1; padding: 12px 15px; font-size: 16px; border: 2px solid #3498db; border-radius: 4px; transition: border-color 0.3s; }
input[type="text"]:focus { border-color: #2980b9; outline: none; }
button { background-color: #3498db; color: white; border: none; padding: 12px 24px; margin-left: 12px; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: bold; transition: background-color 0.3s; }
button:hover { background-color: #2980b9; }
.result { background-color: #f8f9fa; padding: 20px; border-radius: 4px; margin-top: 25px; white-space: pre-wrap; font-family: Consolas, Monaco, monospace; font-size: 14px; border: 1px solid #e0e0e0; overflow: auto; max-height: 400px; }
.error { color: #d32f2f; background-color: #ffebee; border-color: #ffcdd2; }
footer { text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 14px; }
</style>
</head>
<body>
<div class="container">
<h1>网络连通性测试工具</h1>
<form method="POST">
<input type="text" name="target" placeholder="输入要ping的域名或IP地址" required>
<button type="submit">执行Ping测试</button>
</form>
<div class="result">请输入目标地址并点击测试按钮</div>
<footer>本工具仅用于网络诊断 | 使用Python构建</footer>
</div>
</body>
</html>
"""
self.wfile.write(html.encode('utf-8'))
else:
self.send_error(404, "页面不存在")
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode('utf-8')
params = urllib.parse.parse_qs(post_data)
target = params.get('target', [''])[0].strip()
# 安全过滤:只允许字母、数字、点、连字符和冒号(用于IPv6)
if not re.match(r'^[a-zA-Z0-9\.\-:]+$', target):
result = "错误:输入包含非法字符"
result_class = "error"
else:
try:
# 根据操作系统确定ping命令参数
count_param = '-n' if platform.system() == 'Windows' else '-c'
# 执行ping命令(不使用text=True参数,手动处理编码)
process = subprocess.Popen(
['ping', count_param, '4', target],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 获取系统编码
encoding = self._get_system_encoding()
try:
# 设置超时并获取输出
output, error = process.communicate(timeout=10)
# 尝试使用系统编码解码
try:
result = output.decode(encoding) if output else error.decode(encoding)
except UnicodeDecodeError:
# 如果系统编码失败,尝试UTF-8和GBK
try:
result = output.decode('utf-8') if output else error.decode('utf-8')
except:
result = output.decode('gbk', errors='replace') if output else error.decode('gbk', errors='replace')
except subprocess.TimeoutExpired:
process.kill()
output, error = process.communicate()
result = "错误:ping操作超时"
result_class = ""
except Exception as e:
result = f"错误:{str(e)}"
result_class = "error"
self._set_headers()
# 安全转义结果中的HTML特殊字符
result = result.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
# 返回包含结果的HTML页面
result_html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网络连通性测试</title>
<style>
body {{ font-family: "Microsoft YaHei", "Segoe UI", sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f0f8ff; }}
.container {{ background-color: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 15px rgba(0,0,0,0.1); }}
h1 {{ color: #2c3e50; text-align: center; margin-bottom: 25px; }}
form {{ display: flex; margin: 25px 0; }}
input[type="text"] {{ flex-grow: 1; padding: 12px 15px; font-size: 16px; border: 2px solid #3498db; border-radius: 4px; transition: border-color 0.3s; }}
input[type="text"]:focus {{ border-color: #2980b9; outline: none; }}
button {{ background-color: #3498db; color: white; border: none; padding: 12px 24px; margin-left: 12px; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: bold; transition: background-color 0.3s; }}
button:hover {{ background-color: #2980b9; }}
.result {{ background-color: #f8f9fa; padding: 20px; border-radius: 4px; margin-top: 25px; white-space: pre-wrap; font-family: Consolas, Monaco, monospace; font-size: 14px; border: 1px solid #e0e0e0; overflow: auto; max-height: 400px; }}
.error {{ color: #d32f2f; background-color: #ffebee; border-color: #ffcdd2; }}
footer {{ text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 14px; }}
</style>
</head>
<body>
<div class="container">
<h1>网络连通性测试工具</h1>
<form method="POST">
<input type="text" name="target" value="{target}" required>
<button type="submit">执行Ping测试</button>
</form>
<div class="result {result_class}">{result}</div>
<footer>本工具仅用于网络诊断 | 使用Python构建</footer>
</div>
</body>
</html>
"""
self.wfile.write(result_html.encode('utf-8'))
if __name__ == "__main__":
with socketserver.TCPServer(("", PORT), PingHandler) as httpd:
print(f"服务器正在运行,访问地址: http://localhost:{PORT}")
print("按 Ctrl+C 停止服务器")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\n服务器已停止")
作者:wanghongwei
版权声明:本作品遵循<CC BY-NC-ND 4.0>版权协议,商业转载请联系作者获得授权,非商业转载请附上原文出处链接及本声明。

浙公网安备 33010602011771号