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;
|