C++封装modbus tcp客户端和服务端实现通信
时间: 2023-08-04 13:08:27 浏览: 238
可以通过封装modbus库的函数和数据结构来实现C++中的Modbus TCP客户端和服务端。以下是一个简单的示例代码,其中包含了客户端和服务端的封装实现:
```cpp
#include <modbus/modbus.h>
#include <stdexcept>
class ModbusTcpClient {
public:
ModbusTcpClient(const std::string& ip, int port, int slave_id = 1) {
ctx_ = modbus_new_tcp(ip.c_str(), port);
if (!ctx_) {
throw std::runtime_error("Failed to create Modbus context");
}
modbus_set_slave(ctx_, slave_id);
if (modbus_connect(ctx_) == -1) {
throw std::runtime_error("Failed to connect to Modbus server");
}
}
~ModbusTcpClient() {
modbus_close(ctx_);
modbus_free(ctx_);
}
void read_registers(int addr, int nb, uint16_t* dest) {
if (modbus_read_registers(ctx_, addr, nb, dest) == -1) {
throw std::runtime_error("Failed to read Modbus registers");
}
}
void write_registers(int addr, int nb, const uint16_t* src) {
if (modbus_write_registers(ctx_, addr, nb, src) == -1) {
throw std::runtime_error("Failed to write Modbus registers");
}
}
private:
modbus_t* ctx_;
};
class ModbusTcpServer {
public:
ModbusTcpServer(int port, int slave_id = 1) {
ctx_ = modbus_new_tcp("0.0.0.0", port);
if (!ctx_) {
throw std::runtime_error("Failed to create Modbus context");
}
modbus_set_slave(ctx_, slave_id);
mapping_ = modbus_mapping_new(10, 10, 10, 10);
if (!mapping_) {
throw std::runtime_error("Failed to create Modbus mapping");
}
if (modbus_tcp_listen(ctx_, 1) == -1) {
throw std::runtime_error("Failed to listen for Modbus TCP connections");
}
modbus_tcp_accept(ctx_, &client_);
}
~ModbusTcpServer() {
modbus_mapping_free(mapping_);
modbus_close(client_);
modbus_close(ctx_);
modbus_free(client_);
modbus_free(ctx_);
}
void run() {
while (true) {
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
int rc = modbus_receive(client_, query);
if (rc > 0) {
uint16_t addr, nb;
modbus_get_header(client_, query, &addr, MODBUS_FC_READ_HOLDING_REGISTERS, &nb);
if (nb > MODBUS_MAX_READ_REGISTERS) {
nb = MODBUS_MAX_READ_REGISTERS;
}
modbus_reply(client_, query, rc, mapping_->tab_registers + addr, nb);
} else if (rc == -1) {
modbus_close(client_);
modbus_tcp_accept(ctx_, &client_);
}
}
}
private:
modbus_t* ctx_;
modbus_t* client_;
modbus_mapping_t* mapping_;
};
int main() {
// 启动服务端
ModbusTcpServer server(502);
std::thread server_thread([&server](){ server.run(); });
server_thread.detach();
// 启动客户端
ModbusTcpClient client("127.0.0.1", 502);
uint16_t read_data[10];
uint16_t write_data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
client.write_registers(0, 10, write_data);
client.read_registers(0, 10, read_data);
return 0;
}
```
通过封装后,使用起来更加方便,同时也更加安全和稳定。
阅读全文