C++ ModBUS TCP客户端

17 篇文章 1 订阅

https://sourceforge.net/projects/qmodmaster/

 

用Qt写的一个客户端。非常小巧,非常好用。平台通用。内部有一个文件夹libmodbus,可以借来用用。

在github上找了一下都没找到这么好的东西。

 

 

 

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
这是一个基于 Boost 库封装的 C++ Modbus TCP 客户和服务的示例代码: ```cpp #include <iostream> #include <string> #include <boost/asio.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/array.hpp> #include <boost/thread.hpp> using namespace std; using namespace boost::asio; using namespace boost::asio::ip; // Modbus TCP 帧结构体 #pragma pack(push, 1) struct ModbusTCPFrame { uint16_t transaction_id; uint16_t protocol_id; uint16_t length; uint8_t unit_id; uint8_t function_code; uint16_t start_address; uint16_t quantity; }; #pragma pack(pop) // Modbus TCP 客户类 class ModbusTCPClient { public: ModbusTCPClient(string ip_address, uint16_t port) : m_ip_address(ip_address), m_port(port), m_socket(m_io_service) { } // 连接到 Modbus TCP 服务器 bool connect() { try { m_socket.connect(tcp::endpoint(address::from_string(m_ip_address), m_port)); } catch (boost::system::system_error& e) { cerr << "Error: " << e.what() << endl; return false; } return true; } // 发送读取线圈状态请求 bool read_coils(uint16_t start_address, uint16_t quantity, boost::array<uint8_t, 256>& response) { ModbusTCPFrame frame = { 0 }; frame.transaction_id = 1; frame.protocol_id = 0; frame.length = 6; frame.unit_id = 1; frame.function_code = 0x01; frame.start_address = htons(start_address); frame.quantity = htons(quantity); boost::system::error_code ec; m_socket.write_some(buffer(&frame, 6), ec); if (ec) { cerr << "Error: " << ec.message() << endl; return false; } size_t len = m_socket.read_some(buffer(response), ec); if (ec) { cerr << "Error: " << ec.message() << endl; return false; } return true; } private: string m_ip_address; uint16_t m_port; io_service m_io_service; tcp::socket m_socket; }; // Modbus TCP 服务类 class ModbusTCPServer { public: ModbusTCPServer(uint16_t port) : m_port(port), m_acceptor(m_io_service, tcp::endpoint(tcp::v4(), m_port)) { } // 启动 Modbus TCP 服务器 void start() { boost::thread t(boost::bind(&io_service::run, &m_io_service)); while (true) { tcp::socket socket(m_io_service); m_acceptor.accept(socket); boost::thread(boost::bind(&ModbusTCPServer::handle_client, this, socket)); } } private: void handle_client(tcp::socket& socket) { boost::system::error_code ec; while (true) { boost::array<uint8_t, 256> request = { 0 }; size_t len = socket.read_some(buffer(request), ec); if (ec) { cerr << "Error: " << ec.message() << endl; break; } ModbusTCPFrame* frame = (ModbusTCPFrame*)request.data(); if (frame->function_code == 0x01) { uint16_t start_address = ntohs(frame->start_address); uint16_t quantity = ntohs(frame->quantity); boost::array<uint8_t, 256> response = { 0 }; response[0] = frame->transaction_id >> 8; response[1] = frame->transaction_id; response[2] = frame->protocol_id >> 8; response[3] = frame->protocol_id; response[4] = (quantity + 7) / 8; for (int i = 0; i < quantity; i++) { response[5 + i / 8] |= (i % 8 == 0 ? 0x80 : 0) | (i % 8 == 1 ? 0x40 : 0) | (i % 8 == 2 ? 0x20 : 0) | (i % 8 == 3 ? 0x10 : 0) | (i % 8 == 4 ? 0x08 : 0) | (i % 8 == 5 ? 0x04 : 0) | (i % 8 == 6 ? 0x02 : 0) | (i % 8 == 7 ? 0x01 : 0); } socket.write_some(buffer(response, 5 + (quantity + 7) / 8), ec); if (ec) { cerr << "Error: " << ec.message() << endl; break; } } } } private: uint16_t m_port; io_service m_io_service; tcp::acceptor m_acceptor; }; int main() { // 创建 Modbus TCP 客户对象并连接到服务器 ModbusTCPClient client("127.0.0.1", 502); if (!client.connect()) { return -1; } // 发送读取线圈状态请求并输出结果 boost::array<uint8_t, 256> response = { 0 }; if (client.read_coils(0, 16, response)) { for (int i = 0; i < 16; i++) { cout << (response[5 + i / 8] & (1 << (i % 8)) ? "1" : "0"); } cout << endl; } // 创建 Modbus TCP 服务对象并启动服务器 ModbusTCPServer server(502); server.start(); return 0; } ``` 该代码使用 Boost 库实现了 Modbus TCP 客户和服务Modbus TCP 帧结构体使用了 pragma pack 指令进行字节对齐。ModbusTCPClient 类实现了连接到 Modbus TCP 服务器和发送读取线圈状态请求的功能。ModbusTCPServer 类实现了启动 Modbus TCP 服务器和处理客户请求的功能。在 main 函数中先创建 Modbus TCP 客户对象并连接到服务器,然后发送读取线圈状态请求并输出结果。接着创建 Modbus TCP 服务对象并启动服务器,等待客户连接并处理客户请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边闲人2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值