# 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` 文件中的完整示例代码。