XNSim/XNSimHtml/routes/udp-monitor.js

257 lines
7.0 KiB
JavaScript
Raw Permalink Normal View History

2025-04-28 16:41:21 +08:00
const express = require('express');
const router = express.Router();
const dgram = require('dgram');
// 全局变量存储UDP服务器实例和接收到的数据
let udpServer = null;
let udpData = [];
let isMonitoring = false;
let currentPort = null;
let currentIp = null;
// 开始UDP监控
router.post('/start', (req, res) => {
try {
const { port, ip } = req.body;
// 验证端口参数
if (!port || port < 1024 || port > 65535) {
return res.status(400).json({
success: false,
error: '端口号必须在1024-65535之间'
});
}
// 验证IP参数
if (!ip) {
return res.status(400).json({
success: false,
error: 'IP地址不能为空'
});
}
// 如果已经在监控,先停止之前的监控
if (isMonitoring) {
stopUdpServer();
}
// 创建UDP服务器
udpServer = dgram.createSocket('udp4');
currentPort = port;
currentIp = ip;
// 清空之前的数据
udpData = [];
// 监听错误事件
udpServer.on('error', (err) => {
console.error(`UDP服务器错误:`, err);
isMonitoring = false;
udpServer.close();
udpServer = null;
});
// 监听消息事件
udpServer.on('message', (msg, rinfo) => {
// 将收到的数据添加到数据队列
try {
let processedData;
// 尝试将数据解析为JSON
try {
processedData = JSON.parse(msg.toString());
} catch (e) {
// 如果不是JSON则保存为字符串
processedData = msg.toString();
}
// 将数据添加到队列
udpData.push({
timestamp: Date.now(),
source: `${rinfo.address}:${rinfo.port}`,
data: processedData
});
// 限制数据队列大小最多保存1000条记录
if (udpData.length > 1000) {
udpData = udpData.slice(-1000);
}
} catch (error) {
console.error('处理UDP数据时出错:', error);
}
});
// 监听监听事件
udpServer.on('listening', () => {
const address = udpServer.address();
console.log(`UDP数据监控已启动在 ${address.address}:${address.port}`);
isMonitoring = true;
});
// 绑定IP和端口
udpServer.bind(port, ip);
res.json({
success: true,
message: `UDP监控已在 ${ip}:${port} 上启动`
});
} catch (error) {
console.error('启动UDP监控失败:', error);
res.status(500).json({
success: false,
error: '启动UDP监控失败: ' + error.message
});
}
});
// 停止UDP监控
router.post('/stop', (req, res) => {
try {
if (!isMonitoring) {
return res.json({
success: true,
message: '没有正在运行的UDP监控'
});
}
stopUdpServer();
res.json({
success: true,
message: 'UDP监控已停止'
});
} catch (error) {
console.error('停止UDP监控失败:', error);
res.status(500).json({
success: false,
error: '停止UDP监控失败: ' + error.message
});
}
});
// 注入UDP数据
router.post('/inject', (req, res) => {
try {
const { targetIp, targetPort, data } = req.body;
// 验证参数
if (!targetIp) {
return res.status(400).json({
success: false,
error: '目标IP地址不能为空'
});
}
if (!targetPort || targetPort < 1024 || targetPort > 65535) {
return res.status(400).json({
success: false,
error: '目标端口号必须在1024-65535之间'
});
}
if (!data) {
return res.status(400).json({
success: false,
error: '数据内容不能为空'
});
}
// 创建临时UDP客户端
const client = dgram.createSocket('udp4');
// 将数据对象转换为JSON字符串
const message = JSON.stringify(data);
// 发送数据
client.send(message, targetPort, targetIp, (err) => {
// 关闭客户端
client.close();
if (err) {
console.error('发送UDP数据失败:', err);
return res.status(500).json({
success: false,
error: '发送UDP数据失败: ' + err.message
});
}
console.log(`已发送UDP数据到 ${targetIp}:${targetPort}`);
res.json({
success: true,
message: `数据已成功发送到 ${targetIp}:${targetPort}`
});
});
} catch (error) {
console.error('发送UDP数据失败:', error);
res.status(500).json({
success: false,
error: '发送UDP数据失败: ' + error.message
});
}
});
// 获取UDP监控数据
router.get('/data', (req, res) => {
try {
// 创建一个新数组来保存返回的数据
const dataToSend = [...udpData];
// 清空数据队列
udpData = [];
res.json({
success: true,
data: dataToSend,
isMonitoring,
port: currentPort,
ip: currentIp
});
} catch (error) {
console.error('获取UDP监控数据失败:', error);
res.status(500).json({
success: false,
error: '获取UDP监控数据失败: ' + error.message
});
}
});
// 获取当前监控状态
router.get('/status', (req, res) => {
res.json({
success: true,
isMonitoring,
port: currentPort,
ip: currentIp
});
});
// 辅助函数停止UDP服务器
function stopUdpServer() {
if (udpServer) {
try {
udpServer.close();
console.log('UDP监控已停止');
} catch (error) {
console.error('关闭UDP服务器时出错:', error);
}
udpServer = null;
isMonitoring = false;
currentPort = null;
currentIp = null;
}
}
// 当应用程序关闭时确保UDP服务器也关闭
process.on('exit', stopUdpServer);
process.on('SIGINT', () => {
stopUdpServer();
process.exit(0);
});
module.exports = router;