Files
dc-tranlog-service/UDP_MULTICAST_SENDER.md
T
2026-01-26 18:08:01 +08:00

217 lines
6.2 KiB
Markdown
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.
# UDP多播发送功能说明
## 概述
本功能实现了UDP多播发送逻辑,对应C++代码`TLogServer.cpp`中的发送广播机制。作为独立功能,不依赖Spring框架,可以直接使用。
## 功能对应关系
### C++代码对应关系
| C++代码 | Java实现 | 说明 |
|---------|---------|------|
| `m_SendCtrl.Start(m_iSendPort, m_IP.c_str())` | `MulticastSender.initialize()` | 启动UDP多播发送 |
| `m_SendCtrl.AddChannel(m_SendGrpIP.c_str(), m_iSendPort)` | `MulticastSender`构造函数配置 | 配置发送通道 |
| `m_SendCtrl.Send(item)` | `MulticastSender.send(item)` | 发送COP_ITEM数据 |
| `item->GetMessage()` | `COPMessageBuilder.buildMessage(item)` | 构建COP协议消息 |
## 核心组件
### 1. MulticastSender
UDP多播发送器,负责:
- 创建并配置UDP多播Socket
- 发送COP协议数据
- 管理发送状态和监听器
**位置**: `com.afe.dc.tranlog.service.multicast.MulticastSender`
**主要方法**:
- `initialize()`: 初始化发送器
- `send(COPItem item)`: 发送COPItem数据
- `sendRaw(byte[] data)`: 发送原始字节数据
- `close()`: 关闭发送器
- `addListener(SendListener listener)`: 添加发送监听器
### 2. COPMessageBuilder
COP协议消息构建器,负责将`COPItem`对象转换为字节数组(COP协议格式)。
**位置**: `com.afe.dc.tranlog.service.multicast.COPMessageBuilder`
**主要方法**:
- `buildMessage(COPItem item)`: 构建COP协议消息
## 使用示例
### 基本使用
```java
// 1. 创建发送配置
MulticastSender.Config config = new MulticastSender.Config(
5001, // 发送端口
"225.6.7.9" // 多播组IP
);
config.setLocalIp("0.0.0.0") // 本地IP(可选)
.setTtl(1) // TTL值(可选,默认1)
.setLoopbackDisabled(true); // 禁用回环(可选,默认true)
// 2. 创建发送器
MulticastSender sender = new MulticastSender(config);
// 3. 初始化
if (!sender.initialize()) {
System.err.println("初始化失败");
return;
}
try {
// 4. 创建COPItem数据
COPItem item = COPItem.builder()
.itemNo(12345L)
.msgType(COPItem.MsgType.MGT_UPDATE)
.build();
// 添加FID字段
item.addField(COPItem.FID.FID_TRAN_LOG, "交易数据");
item.addField(COPItem.FID.FID_ASK, 100.5f);
item.addField(COPItem.FID.FID_BID, 100.3f);
// 5. 发送数据
boolean success = sender.send(item);
} finally {
// 6. 关闭发送器
sender.close();
}
```
### 使用发送监听器
```java
// 添加发送监听器
sender.addListener(new MulticastSender.SendListener() {
@Override
public void onSendSuccess(COPItem item, int bytesSent) {
System.out.println("发送成功 - itemNo: " + item.getItemNo()
+ ", 大小: " + bytesSent + " 字节");
}
@Override
public void onSendError(COPItem item, Exception error) {
System.err.println("发送失败 - itemNo: " + item.getItemNo()
+ ", 错误: " + error.getMessage());
}
});
```
### 发送原始字节数据
```java
byte[] rawData = new byte[]{0x01, 0x02, 0x03, 0x04};
sender.sendRaw(rawData);
```
## 配置说明
### MulticastSender.Config
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| sendPort | int | 是 | - | 发送端口 |
| groupIp | String | 是 | - | 多播组IP地址 |
| localIp | String | 否 | "0.0.0.0" | 本地网络接口IP地址 |
| ttl | int | 否 | 1 | TTL值(Time To Live) |
| loopbackDisabled | boolean | 否 | true | 是否禁用回环 |
### 配置方法
```java
MulticastSender.Config config = new MulticastSender.Config(5001, "225.6.7.9")
.setLocalIp("192.168.1.100") // 链式调用设置本地IP
.setTtl(2) // 设置TTL
.setLoopbackDisabled(false); // 允许回环
```
## COP协议格式
当前实现的COP协议格式:
```
消息头(16字节):
- 消息类型(1字节)
- ItemNo(4字节,小端序)
- 其他头部信息(11字节,当前用0填充)
FID字段(每个字段):
- FID编号(2字节)
- 数据类型(1字节)
- 数据长度(2字节)
- 数据内容(变长)
```
### 支持的数据类型
| 数据类型 | 标识 | Java类型 | 大小 |
|---------|------|----------|------|
| CHAR | 0x01 | Byte, Character | 1字节 |
| SHORT | 0x02 | Short | 2字节 |
| INT | 0x04 | Integer | 4字节 |
| LONG | 0x08 | Long | 8字节 |
| FLOAT | 0x10 | Float | 4字节 |
| DOUBLE | 0x20 | Double | 8字节 |
| STRING | 0x40 | String | 变长 |
| BYTE_ARRAY | 0x80 | byte[] | 变长 |
## 注意事项
1. **独立功能**: 本功能不依赖Spring框架,可以在任何Java应用中使用。
2. **线程安全**: `MulticastSender`不是线程安全的,如果需要在多线程环境中使用,需要外部同步。
3. **资源管理**: 使用完毕后务必调用`close()`方法释放资源。
4. **网络权限**: 在某些操作系统上,发送UDP多播数据可能需要特殊权限。
5. **防火墙**: 确保防火墙允许UDP数据包通过配置的端口。
6. **TTL值**: TTL值决定了数据包可以经过的路由器数量,通常设置为1(本地网络)或更大的值(跨网络)。
7. **回环**: 如果`loopbackDisabled`为`true`,发送的数据不会回环到本地接收端,适合生产环境。
## 故障排查
### 初始化失败
1. 检查多播组IP地址是否有效(必须是224.0.0.0到239.255.255.255之间)
2. 检查端口是否被占用
3. 检查网络接口是否正确
4. 查看日志中的详细错误信息
### 发送失败
1. 检查网络连接
2. 检查防火墙设置
3. 检查多播组地址和端口是否正确
4. 查看日志中的详细错误信息
### 数据格式问题
1. 检查COP协议格式是否与接收端一致
2. 检查数据类型是否正确
3. 查看`COPMessageBuilder`的构建逻辑
## 扩展
如果需要扩展功能,可以:
1. **自定义协议格式**: 修改`COPMessageBuilder`以支持不同的协议格式
2. **批量发送**: 添加批量发送方法
3. **异步发送**: 添加异步发送支持
4. **发送统计**: 添加发送统计和监控功能
5. **重试机制**: 添加发送失败重试机制
## 完整示例
参考 `MulticastSenderExample.java` 文件中的完整示例代码。