GrabBag/Module/ModbusTCPServer/_Inc/ModbusTCPServer.h

140 lines
5.0 KiB
C
Raw Normal View History

#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>
// Platform-specific includes for socket operations
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>
#endif
// 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