126 lines
4.6 KiB
C++
126 lines
4.6 KiB
C++
#ifndef MODBUS_TCP_SERVER_H
|
||
#define MODBUS_TCP_SERVER_H
|
||
|
||
#include "IYModbusTCPServer.h"
|
||
#include <functional>
|
||
#include <vector>
|
||
#include <thread>
|
||
#include <mutex>
|
||
#include <atomic>
|
||
#include <memory>
|
||
#include <unordered_map>
|
||
|
||
// libmodbus headers
|
||
extern "C" {
|
||
#include "modbus.h"
|
||
#include "modbus-tcp.h"
|
||
}
|
||
|
||
class ModbusTCPServer : public IYModbusTCPServer {
|
||
private:
|
||
// 客户端连接结构体
|
||
struct ClientConnection {
|
||
int socket;
|
||
modbus_t* modbusCtx;
|
||
|
||
ClientConnection(int sock, modbus_t* ctx) : socket(sock), modbusCtx(ctx) {}
|
||
|
||
~ClientConnection() {
|
||
if (modbusCtx) {
|
||
modbus_free(modbusCtx);
|
||
}
|
||
#ifdef _WIN32
|
||
if (socket != -1) {
|
||
closesocket(socket);
|
||
}
|
||
#else
|
||
if (socket != -1) {
|
||
close(socket);
|
||
}
|
||
#endif
|
||
}
|
||
};
|
||
|
||
public:
|
||
ModbusTCPServer();
|
||
virtual ~ModbusTCPServer() override;
|
||
|
||
// 实现IYModbusTCPServer接口
|
||
// 启动/停止服务器
|
||
virtual int start(int port = 502, int maxConnections = 10) override;
|
||
virtual void stop() override;
|
||
bool isRunning() const { return m_isRunning.load(); }
|
||
|
||
// 设置回调函数
|
||
virtual void setWriteCoilsCallback(WriteCoilsCallback callback) override { m_writeCoilsCallback = callback; }
|
||
virtual void setWriteRegistersCallback(WriteRegistersCallback callback) override { m_writeRegistersCallback = callback; }
|
||
virtual void setConnectionStatusCallback(ConnectionStatusCallback callback) override { m_connectionStatusCallback = callback; }
|
||
|
||
// 数据更新接口 - 线程安全
|
||
virtual void updateCoil(uint16_t address, bool value) override;
|
||
virtual void updateCoils(uint16_t startAddress, const std::vector<bool>& values) override;
|
||
virtual void updateDiscreteInput(uint16_t address, bool value) override;
|
||
virtual void updateDiscreteInputs(uint16_t startAddress, const std::vector<bool>& values) override;
|
||
virtual void updateHoldingRegister(uint16_t address, uint16_t value) override;
|
||
virtual void updateHoldingRegisters(uint16_t startAddress, const std::vector<uint16_t>& values) override;
|
||
virtual void updateInputRegister(uint16_t address, uint16_t value) override;
|
||
virtual void updateInputRegisters(uint16_t startAddress, const std::vector<uint16_t>& values) override;
|
||
|
||
// 获取错误信息
|
||
std::string getLastError() const;
|
||
|
||
private:
|
||
// 服务器主循环
|
||
void serverLoop();
|
||
|
||
// 客户端连接管理
|
||
void handleNewConnection();
|
||
void handleClientData(std::shared_ptr<ClientConnection> client);
|
||
void removeClient(int socket);
|
||
void processModbusRequest(std::shared_ptr<ClientConnection> client, const uint8_t* query, int queryLength);
|
||
|
||
// 数据读取处理器(libmodbus内部调用)
|
||
static int readCoilsHandler(modbus_t *ctx, int function_code, int addr, int nb, uint8_t *rsp, int *rsp_length, void *user_data);
|
||
static int readDiscreteInputsHandler(modbus_t *ctx, int function_code, int addr, int nb, uint8_t *rsp, int *rsp_length, void *user_data);
|
||
static int readHoldingRegistersHandler(modbus_t *ctx, int function_code, int addr, int nb, uint8_t *rsp, int *rsp_length, void *user_data);
|
||
static int readInputRegistersHandler(modbus_t *ctx, int function_code, int addr, int nb, uint8_t *rsp, int *rsp_length, void *user_data);
|
||
|
||
// 数据写入函数(libmodbus内部调用)
|
||
static int writeCoilsHandler(modbus_t *ctx, int function_code, int addr, int nb, const uint8_t *req, int req_length, void *user_data);
|
||
static int writeRegistersHandler(modbus_t *ctx, int function_code, int addr, int nb, const uint8_t *req, int req_length, void *user_data);
|
||
|
||
private:
|
||
// libmodbus context
|
||
modbus_t* m_modbusCtx;
|
||
modbus_mapping_t* m_mapping;
|
||
|
||
// 服务器状态
|
||
std::atomic<bool> m_isRunning;
|
||
std::atomic<bool> m_shouldStop;
|
||
std::unique_ptr<std::thread> m_serverThread;
|
||
int m_serverSocket;
|
||
int m_port;
|
||
int m_maxConnections;
|
||
|
||
// 客户端连接管理
|
||
std::unordered_map<int, std::shared_ptr<ClientConnection>> m_clients;
|
||
std::mutex m_clientsMutex;
|
||
|
||
// 数据存储 - 使用libmodbus的mapping结构
|
||
std::mutex m_dataMutex;
|
||
|
||
// 回调函数
|
||
WriteCoilsCallback m_writeCoilsCallback;
|
||
WriteRegistersCallback m_writeRegistersCallback;
|
||
ConnectionStatusCallback m_connectionStatusCallback;
|
||
|
||
// 错误信息
|
||
mutable std::mutex m_errorMutex;
|
||
std::string m_lastError;
|
||
|
||
// 设置错误信息
|
||
void setLastError(const std::string& error);
|
||
};
|
||
|
||
#endif // MODBUS_TCP_SERVER_H
|