使用libmodbus编写一个modbus tcp服务器

安装libmodbus

sudo apt install libmodbus-dev

构建工程目录

mkdir modbus_test
cd modbus_test
mkdir src
touch CMakelists.txt
touch src/main.cc

编写server代码,main.cc

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <iostream>
#define SERVER_ID       1       //从端设备地址
#include <modbus/modbus.h>
using namespace std;
int main(int argc, char *argv[])
{
    int server_socket = -1;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    ctx = modbus_new_tcp(NULL,502);
    modbus_set_debug(ctx,FALSE);

    //modbus_set_slave(ctx,SERVER_ID);

    //申请内存区用于存放寄存器数据
    mb_mapping = modbus_mapping_new(8,8,10,10);
    if(mb_mapping == NULL)
    {
        fprintf(stderr,"Failed mapping:%s\n",modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    //开始监听端口
    server_socket = modbus_tcp_listen(ctx,1);
    if(server_socket == -1)
    {
        fprintf(stderr,"Unable to listen TCP.\n");
        modbus_free(ctx);
        return -1;
    }


    // 开始接收数据
    modbus_tcp_accept(ctx, &server_socket);

    printf("accept\n");
    while(1)
    {
        uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
        int rc;

        rc = modbus_receive(ctx,query); //获取查询报文
        if(rc >= 0)
        {
            for (int i = 0; i < rc; ++i) {
                printf("%02x ", query[i]);
            }
            printf("\n");

            /* rc is the query size */
            //mb_mapping->tab_registers[1] = 0x2333;   // 将2333写入地址为1的保持寄存器,可简单理解为发送到客户端
            //modbus_reply(ctx,query,rc,mb_mapping); // 回复响应报文
            modbus_reply_exception(ctx, query, 1);
            //cout<<mb_mapping->tab_registers[0]<<endl;// 打印第一个保持寄存器
        }
        else
        {
            // Connection closed by the client or error
            printf("Connection Closed.\n");

            //Close ctx
            modbus_close(ctx);

            //等待下一个客户端报文
            modbus_tcp_accept(ctx,&server_socket);
        }

    }

    printf("Quit the loop:%s\n",modbus_strerror(errno));

    modbus_mapping_free(mb_mapping);
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}

编写CMakeLists.txt

project(modbus_test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O0 -std=c++17 ${CMAKE_CXX_FLAGS}")


#include_directories(src)
aux_source_directory(src SRCS)

add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} pthread modbus)

编译运行

mkdir build
cd build
cmake ..
make
sudo ./modbus_test

测试

经过上一步,modbus tcp master运行在主机的502端口,等待modbus slave连接。
我们使用modbus poll工具连接后,即可在服务器端收到slave发送的指令。我们只需要对收到的指令进行解析并处理即可实现特定功能的modbus tcp 服务器

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
为了编写MODBUS TCP服务器和客户端程序,我们需要使用Java Modbus库来实现。以下是一个简单的示例程序,分别演示了如何创建MODBUS TCP服务器和客户端。 ### MODBUS TCP服务器 ```java import java.net.*; import java.io.*; import java.util.*; import net.wimpi.modbus.net.*; import net.wimpi.modbus.procimg.*; import net.wimpi.modbus.ModbusException; public class ModbusTCPServer { public static void main(String[] args) { try { // 创建一个Modbus TCP服务器 ModbusTCPListener listener = new ModbusTCPListener(3); listener.setPort(502); listener.start(); System.out.println("Modbus TCP服务器已启动"); // 创建一个简单的数据模型 SimpleProcessImage spi = new SimpleProcessImage(); spi.addDigitalOut(new SimpleDigitalOut(true)); spi.addDigitalIn(new SimpleDigitalIn(false)); spi.addRegister(new SimpleRegister(251)); spi.addInputRegister(new SimpleInputRegister(45)); // 将数据模型绑定到Modbus TCP服务器 listener.setModbusCoupler(new ModbusCoupler(spi,listener.getModbusCoupler())); } catch (Exception ex) { ex.printStackTrace(); } } } ``` ### MODBUS TCP客户端 ```java import java.net.*; import java.io.*; import java.util.*; import net.wimpi.modbus.*; import net.wimpi.modbus.msg.*; import net.wimpi.modbus.io.*; import net.wimpi.modbus.net.*; import net.wimpi.modbus.util.*; import net.wimpi.modbus.procimg.*; public class ModbusTCPClient { public static void main(String[] args) { try { // 创建一个Modbus TCP客户端 TCPMasterConnection con = new TCPMasterConnection(InetAddress.getLocalHost()); con.setPort(502); con.connect(); // 创建一个读取寄存器的请求 ReadMultipleRegistersRequest req = new ReadMultipleRegistersRequest(0, 1); req.setUnitID(3); // 发送请求并获取响应 ModbusTCPTransaction trans = new ModbusTCPTransaction(con); trans.setRequest(req); trans.execute(); ReadMultipleRegistersResponse res = (ReadMultipleRegistersResponse) trans.getResponse(); // 打印响应的值 System.out.println(res.getRegisterValue(0)); // 断开连接 con.close(); } catch (Exception ex) { ex.printStackTrace(); } } } ``` 以上是一个简单的MODBUS TCP服务器和客户端的示例程序,您可以根据自己的需要进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值