init
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# 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` 文件中的完整示例代码。
|
||||
Reference in New Issue
Block a user