一个基于 Rust 的高性能报警信号监听和转发系统,专门用于接收和解析符合特定协议的UDP报警数据包,并将其转发到指定的HTTP接口。
- 🔍 协议解析: 支持设备状态命令(0x02)报文的完整解析
- 🔧 校验和验证: 自动计算和验证报文校验和(sum % 256)
- 📡 UDP监听: 异步UDP服务器,高并发处理报警包
- 🌐 HTTP转发: 支持多种HTTP方法(GET/POST/PUT/DELETE/PATCH)
- 🔐 多种认证: Basic、Bearer Token、API Key认证支持
- 🔄 重试机制: 指数退避重试,确保消息可靠传输
- ⚙️ 灵活配置: TOML配置文件 + 环境变量覆盖
- 📝 详细日志: 分级日志记录,便于调试和监控
- 🧪 全面测试: 单元测试和集成测试覆盖
- Rust 1.70+
- Tokio 异步运行时
- 网络连接(用于HTTP转发)
git clone https://github.com/LiPingFeel/udp_service.git
cd udp_service编辑 config.toml 文件:
[server]
listen_address = "127.0.0.1"
listen_port = 8088
buffer_size = 1024
[forwarding]
target_url = "http://localhost:3000/api/alarms"
method = "POST"
enabled = true
[forwarding.headers]
"Content-Type" = "application/json"
"User-Agent" = "AlarmSystem/1.0"# 开发模式
cargo run
# 生产模式
cargo build --release
./target/release/udp_service# 使用 netcat 发送测试包
echo -ne '\x0A\x01\x02\x00\x00\x00\x02\x05\x01\x15' | nc -u 127.0.0.1 8088| 字节序号 | 名称 | 类型/范围 | 说明 |
|---|---|---|---|
| 1 | 帧长度 | 0x0A ~ 0x0C | 总字节数(含校验和) |
| 2 | 通讯机地址 | 0~239 | 主机标识 |
| 3 | 设备地址 | 0~239 | 目标设备标识 |
| 4 | 用户组编号高字节 | 0~99 | 高位部分(通常为0) |
| 5 | 用户组编号低字节 | 0~99 | 低位部分(通常为0) |
| 6 | 扩展备用 | 0~255 | 保留字段 |
| 7 | 命令类型 | 固定 0x02 | 设备状态命令标识 |
| 8 | 防区报警状态 | Bit0~Bit7 | 对应防区1~8: 0=正常,1=报警 |
| 9 | 设备状态 | Bit0~Bit7 | 详见设备状态位定义 |
| 10 | 防区撤布防状态 | Bit0~Bit7 | 可选: 0=布防,1=撤防 |
| 11 | 防区实时触发状态 | Bit0~Bit7 | 可选: 0=正常,1=触发 |
| N+1 | 校验和 | 0x00~0xFF | (字节1+...+字节N) % 256 |
| 位 | 功能 | 说明 |
|---|---|---|
| Bit0 | 布防状态 | 0=布防, 1=撤防 |
| Bit1 | 紧急求助 | 1=触发紧急求助 |
| Bit2 | 设备故障 | 1=设备发生故障 |
| Bit3 | 留守布防 | 1=留守布防模式 |
| Bit4 | 检修模式 | 1=设备处于检修模式 |
| Bit5 | 欠压报警 | 1=设备电压过低 |
| Bit6-7 | 备用 | 保留位 |
基本报警包 (10字节):
0A 01 02 00 00 00 02 05 01 15
- 帧长度: 0x0A (10字节)
- 通讯机地址: 0x01
- 设备地址: 0x02
- 防区报警: 0x05 (防区1和3报警)
- 设备状态: 0x01 (撤防状态)
- 校验和: 0x15
[server]
listen_address = "127.0.0.1" # UDP监听地址
listen_port = 8088 # UDP监听端口
buffer_size = 1024 # 接收缓冲区大小
heartbeat_timeout = 30 # 心跳超时时间(秒)[forwarding]
target_url = "http://localhost:3000/api/alarms" # 转发目标URL
method = "POST" # HTTP方法
timeout = 30 # 请求超时(秒)
enabled = true # 是否启用转发
# 自定义请求头
[forwarding.headers]
"Content-Type" = "application/json"
"Authorization" = "Bearer your-token"
# 重试配置
[forwarding.retry]
max_attempts = 3 # 最大重试次数
retry_interval = 5 # 重试间隔(秒)
backoff_multiplier = 2.0 # 退避系数
max_backoff = 60 # 最大退避时间(秒)Basic 认证:
[forwarding.auth]
auth_type = "basic"
username = "your_username"
password = "your_password"Bearer Token 认证:
[forwarding.auth]
auth_type = "bearer"
token = "your_bearer_token"API Key 认证:
[forwarding.auth]
auth_type = "api_key"
api_key = "your_api_key"
api_key_header = "X-API-Key"系统支持通过环境变量覆盖配置:
# Windows PowerShell
$env:ALARM_LISTEN_ADDRESS = "0.0.0.0"
$env:ALARM_LISTEN_PORT = "9999"
$env:ALARM_FORWARD_URL = "https://api.example.com/alarms"
$env:ALARM_AUTH_TYPE = "bearer"
$env:ALARM_AUTH_TOKEN = "your-secret-token"
# Linux/macOS
export ALARM_LISTEN_ADDRESS="0.0.0.0"
export ALARM_LISTEN_PORT="9999"
export ALARM_FORWARD_URL="https://api.example.com/alarms"系统会将解析后的报警信息转换为JSON格式发送:
{
"timestamp": 1694505600,
"alarm_type": "zone_alarm",
"device": {
"comm_addr": 1,
"device_addr": 2,
"user_group": "0.0"
},
"details": {
"device_status": {
"armed": false,
"emergency": false,
"fault": false,
"stay_armed": false,
"maintenance": false,
"low_voltage": false
},
"alarm_zones": [1, 3],
"disarmed_zones": null,
"triggered_zones": null,
"description": {
"通讯机地址": "1",
"设备地址": "2",
"设备状态": "撤防",
"报警防区": "1, 3"
}
},
"raw_data": "0A 01 02 00 00 00 02 05 01 15"
}# 运行所有测试
cargo test
# 运行单元测试
cargo test --lib
# 运行集成测试
cargo test --test integration_tests
# 详细输出
cargo test -- --nocapture# 启用调试日志
RUST_LOG=debug cargo run
# 启用详细日志
RUST_LOG=trace cargo run# 代码检查
cargo check
# 格式化
cargo fmt
# Clippy 静态分析
cargo clippyudp_service/
├── src/
│ ├── main.rs # 应用程序入口
│ ├── lib.rs # 库入口
│ ├── alarm_server.rs # UDP服务器实现
│ ├── protocol.rs # 报警协议定义和解析
│ ├── forwarder.rs # HTTP转发器
│ └── config.rs # 配置管理
├── tests/
│ └── integration_tests.rs # 集成测试
├── config.toml # 配置文件
├── Cargo.toml # 项目依赖
└── README.md # 项目文档
1. UDP端口被占用
# Windows 查看端口占用
netstat -ano | findstr :8088
# 更改配置文件中的端口
listen_port = 80892. 日志不显示
# 设置日志级别
set RUST_LOG=info
cargo run3. 转发失败
- 检查目标URL是否可访问
- 验证认证配置是否正确
- 查看详细错误日志
4. 报文解析失败
- 检查校验和计算是否正确
- 验证帧长度是否匹配实际长度
- 确认命令类型是否为0x02
error: 仅错误信息warn: 错误和警告info: 常规运行信息debug: 调试信息trace: 详细跟踪信息
- Fork 项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
- Tokio - 异步运行时
- Serde - 序列化框架
- reqwest - HTTP客户端
- pretty_env_logger - 日志格式化
- 项目主页: https://github.com/LiPingFeel/udp_service
- 问题反馈: Issues
⭐ 如果这个项目对您有帮助,请给个星标!