# Modbus TCP 服务器模块

基于libmodbus库的Modbus TCP服务器实现，提供完整的Modbus TCP服务器功能和回调机制。

## 功能特性

- 基于libmodbus的稳定实现
- 支持多客户端并发连接
- 完整的Modbus功能码支持
- 写操作回调机制，支持应用层错误码反馈
- 线程安全的数据访问和更新接口
- 跨平台支持（Windows/Linux）

## 支持的Modbus功能

### 读操作（自动处理）
- 读取线圈（0x01）
- 读取离散输入（0x02）  
- 读取保持寄存器（0x03）
- 读取输入寄存器（0x04）

### 写操作（支持回调）
- 写单个线圈（0x05）
- 写单个保持寄存器（0x06）
- 写多个线圈（0x0F）
- 写多个保持寄存器（0x10）

## API接口

### 基本操作
```cpp
#include "ModbusTCPServer.h"

ModbusTCPServer server;

// 启动服务器
if (server.start(502, 10)) {
    // 服务器启动成功
}

// 停止服务器
server.stop();
```

### 设置写操作回调
```cpp
// 设置写线圈回调
server.setWriteCoilsCallback([](uint8_t unitId, uint16_t address, uint16_t quantity, const uint8_t* values) -> ModbusTCPServer::ErrorCode {
    // 处理写线圈请求
    // unitId: 单元ID
    // address: 起始地址
    // quantity: 数量
    // values: 写入的值
    
    // 返回错误码
    return ModbusTCPServer::ErrorCode::SUCCESS;
});

// 设置写寄存器回调
server.setWriteRegistersCallback([](uint8_t unitId, uint16_t address, uint16_t quantity, const uint16_t* values) -> ModbusTCPServer::ErrorCode {
    // 处理写寄存器请求
    // 检查地址范围、权限等
    
    if (address >= 1000 && address < 2000) {
        // 允许写入
        return ModbusTCPServer::ErrorCode::SUCCESS;
    } else {
        // 拒绝写入 - 非法地址
        return ModbusTCPServer::ErrorCode::ILLEGAL_DATA_ADDRESS;
    }
});
```

### 数据更新接口
```cpp
// 更新单个数据
server.updateCoil(0, true);
server.updateHoldingRegister(100, 1234);
server.updateDiscreteInput(50, false);
server.updateInputRegister(200, 5678);

// 批量更新数据
std::vector<bool> coils = {true, false, true, false};
server.updateCoils(0, coils);

std::vector<uint16_t> registers = {1000, 2000, 3000};
server.updateHoldingRegisters(100, registers);
```

## 错误代码

服务器支持标准的Modbus异常代码：

```cpp
enum class ErrorCode {
    SUCCESS = 0,                        // 成功
    ILLEGAL_FUNCTION = 1,               // 非法功能码
    ILLEGAL_DATA_ADDRESS = 2,           // 非法数据地址
    ILLEGAL_DATA_VALUE = 3,             // 非法数据值
    SERVER_FAILURE = 4,                 // 服务器故障
    ACKNOWLEDGE = 5,                    // 确认
    SERVER_BUSY = 6,                    // 服务器忙
    NEGATIVE_ACKNOWLEDGE = 7,           // 否定确认
    MEMORY_PARITY = 8,                  // 内存奇偶校验错误
    GATEWAY_PATH_UNAVAILABLE = 10,      // 网关路径不可用
    GATEWAY_TARGET_FAILED = 11          // 网关目标设备响应失败
};
```

## 完整使用示例

```cpp
#include "ModbusTCPServer.h"
#include <iostream>
#include <thread>
#include <chrono>

int main() {
    ModbusTCPServer server;
    
    // 设置写操作回调
    server.setWriteCoilsCallback([](uint8_t unitId, uint16_t address, uint16_t quantity, const uint8_t* values) {
        std::cout << "写线圈请求 - 单元ID: " << (int)unitId 
                  << ", 地址: " << address 
                  << ", 数量: " << quantity << std::endl;
        return ModbusTCPServer::ErrorCode::SUCCESS;
    });
    
    server.setWriteRegistersCallback([](uint8_t unitId, uint16_t address, uint16_t quantity, const uint16_t* values) {
        std::cout << "写寄存器请求 - 单元ID: " << (int)unitId 
                  << ", 地址: " << address 
                  << ", 数量: " << quantity << std::endl;
        
        // 检查地址范围
        if (address < 1000) {
            return ModbusTCPServer::ErrorCode::ILLEGAL_DATA_ADDRESS;
        }
        
        return ModbusTCPServer::ErrorCode::SUCCESS;
    });
    
    // 启动服务器
    if (!server.start(502, 10)) {
        std::cerr << "启动服务器失败: " << server.getLastError() << std::endl;
        return -1;
    }
    
    std::cout << "Modbus TCP服务器已启动，端口: 502" << std::endl;
    
    // 定期更新数据
    for (int i = 0; i < 100; ++i) {
        server.updateHoldingRegister(1000, i);
        server.updateCoil(0, i % 2 == 0);
        
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    // 停止服务器
    server.stop();
    std::cout << "服务器已停止" << std::endl;
    
    return 0;
}
```

## 编译说明

### 依赖
- Qt 5.x 或更高版本
- C++17 编译器
- libmodbus源码（已包含在VrNets模块中）

### 构建
```bash
qmake ModbusTCPServer.pro
make
```

### 使用
该模块编译为静态库，在其他项目中包含：
```pro
LIBS += -L../Module/ModbusTCPServer -lModbusTCPServer
INCLUDEPATH += ../Module/ModbusTCPServer/Inc
```

## 特性说明

### 多客户端支持
- 支持同时处理多个客户端连接
- 使用select事件驱动模型，单线程处理所有客户端
- 高效的资源利用，避免线程过多的问题
- 线程安全的数据访问

### 数据存储
- 内部使用libmodbus的mapping结构存储数据
- 支持10000个线圈、离散输入、保持寄存器和输入寄存器
- 所有数据操作都是线程安全的

### 回调机制
- 写操作会触发用户定义的回调函数
- 回调函数可以返回错误码来拒绝写操作
- 支持异步处理和验证

### 错误处理
- 完整的错误处理和状态反馈
- 支持标准Modbus异常代码
- 详细的错误信息获取接口 