XNSim/XNSimHtml/routes/udp-monitor.js
2025-04-28 16:41:21 +08:00

257 lines
7.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;