在写一个热门C++封装modbus tcp作为客户端和服务端的程序
时间: 2024-02-20 20:59:43 浏览: 135
C#编写Modbus TCP客户端程序
好的,我可以为您提供一个基于boost.asio的C++封装modbus tcp作为客户端和服务端的程序的框架代码,您可以根据自己的需求进行修改和完善。
以下是客户端的代码:
```cpp
#include <iostream>
#include <boost/asio.hpp>
#include <modbus/modbus.h>
#include <stdexcept>
#include <array>
class ModbusTCPClient {
public:
ModbusTCPClient(const std::string& ip_address, int port) : socket(io_context) {
boost::asio::ip::tcp::resolver resolver(io_context);
boost::asio::ip::tcp::resolver::query query(ip_address, std::to_string(port));
endpoint = resolver.resolve(query);
}
void connect() {
boost::asio::connect(socket, endpoint);
}
void disconnect() {
socket.close();
}
void read_registers(int address, int count, uint16_t* dest) {
std::array<uint8_t, MODBUS_TCP_MAX_ADU_LENGTH> request, response;
int request_len = modbus_write_read_registers_request(address, count, request.data());
boost::asio::write(socket, boost::asio::buffer(request.data(), request_len));
int response_len = boost::asio::read(socket, boost::asio::buffer(response));
if (response_len == -1) {
throw std::runtime_error("Failed to read response from Modbus server.");
}
int result = modbus_write_read_registers_response(dest, response.data());
if (result == -1) {
throw std::runtime_error("Failed to parse response from Modbus server.");
}
}
void write_registers(int address, int count, const uint16_t* src) {
std::array<uint8_t, MODBUS_TCP_MAX_ADU_LENGTH> request, response;
int request_len = modbus_write_registers_request(address, count, src, request.data());
boost::asio::write(socket, boost::asio::buffer(request.data(), request_len));
int response_len = boost::asio::read(socket, boost::asio::buffer(response));
if (response_len == -1) {
throw std::runtime_error("Failed to read response from Modbus server.");
}
int result = modbus_write_registers_response(response.data());
if (result == -1) {
throw std::runtime_error("Failed to parse response from Modbus server.");
}
}
private:
boost::asio::io_context io_context;
boost::asio::ip::tcp::socket socket;
boost::asio::ip::tcp::resolver::results_type endpoint;
};
```
以下是服务端的代码:
```cpp
#include <iostream>
#include <boost/asio.hpp>
#include <modbus/modbus.h>
#include <stdexcept>
#include <array>
class ModbusTCPServer {
public:
ModbusTCPServer(int port) : acceptor(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) {
start_accept();
}
void start_accept() {
modbus_ctx = modbus_new_tcp("0.0.0.0", 0);
if (!modbus_ctx) {
throw std::runtime_error("Failed to create Modbus TCP context.");
}
boost::asio::ip::tcp::socket socket(io_context);
acceptor.accept(socket);
boost::asio::post(io_context, [this, socket]() {
handle_client(std::move(socket));
});
start_accept();
}
void handle_client(boost::asio::ip::tcp::socket socket) {
try {
while (true) {
std::array<uint8_t, MODBUS_TCP_MAX_ADU_LENGTH> request, response;
int request_len = boost::asio::read(socket, boost::asio::buffer(request));
if (request_len == -1) {
throw std::runtime_error("Failed to read request from Modbus client.");
}
int response_len = modbus_reply(modbus_ctx, request.data(), request_len, response.data());
if (response_len == -1) {
throw std::runtime_error("Failed to generate response for Modbus client.");
}
boost::asio::write(socket, boost::asio::buffer(response.data(), response_len));
}
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
private:
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor;
modbus_t* modbus_ctx;
};
```
使用示例:
```cpp
#include <iostream>
int main() {
try {
ModbusTCPClient client("127.0.0.1", 502);
client.connect();
uint16_t registers[10];
client.read_registers(0, 10, registers);
for (int i = 0; i < 10; i++) {
std::cout << "Register " << i << ": " << registers[i] << std::endl;
}
client.write_registers(0, 10, registers);
client.disconnect();
ModbusTCPServer server(502);
boost::asio::io_context io_context;
boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
signals.async_wait([&io_context](boost::system::error_code, int) {
io_context.stop();
});
io_context.run();
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
```
以上代码仅供参考,具体实现需要根据您的需求进行修改和完善。
阅读全文