257 lines
7.0 KiB
JavaScript
257 lines
7.0 KiB
JavaScript
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;
|