# 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 coils = {true, false, true, false}; server.updateCoils(0, coils); std::vector 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 #include #include 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异常代码 - 详细的错误信息获取接口