modbus简介

modbus协议是7层结构中的应用层的一种请求应答协议
分为
1 串行链路上的MODBUS
    MODBUS串行链路取决于TIA/EIA标准:232-F和485-A。
    串行链路协议是一个主从协议,同一时刻只有一个主节点连接于总线,1个或多个子节点连接于一个串行总线。子节点间不会相互通信,主节点同一时刻只会发起一个modbus事务。
2 TCP/IP上的MODBUS
    MODBUS TCP/IP取决于IETF标准:RFC793 和RFC791有关。




在TCP/IP上使用一种专用报文头识别MODBUS应用数据单元。将这种报文头称为MBAP报文
头(MODBUS 协议报文头)。

报文头为7 个字节长:
事务处理标识符:用于事务处理配对。在响应中,MODBUS服务器复制请求的事务处理标识符。
协议标识符:用于系统内的多路复用。通过值0 识别MODBUS 协议。
长度:长度域是下一个域的字节数,包括单元标识符和数据域。
单元标识符:为了系统内路由,使用这个域。专门用于通过以太网TCP-IP网络和MODBUS串
行链路之间的网关对MODBUS或MODBUS+串行链路从站的通信。MODBUS客户机在请求中设置
这个域,在响应中服务器必须利用相同的值返回这个域。


博主举个我实际应用的例子,下面是读取保持寄存器的报文
 (1)0x00 (2)0x01 (3)0x00 (4)0x00 (5)0x00 (6)0x06 (7)0x01 (8)0x03 (9)0x00 (10)0x0B (11)0x00 (12)0x01

1,2     为客户端生成标识,服务端复制并返回
3,4     0代表modbus协议
5.6     长度,包括单元标识和数据域
7        从站识别码
8        功能码
9,10   起始地址
11,12 寄存器数量

 
下面是java代码,我是继承了modbus4j的框架
1 服务端

package com.serotonin.modbus4j.test;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.serotonin.modbus4j.sero.io.StreamUtils;

public class Test {
    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(502);
        while (true)
            new SocketThread(ss.accept());
    }
    
    static class SocketThread extends Thread {
        Socket s;
        InputStream in;
        SocketThread(Socket s) {
            System.out.println("Socket opened");
            try {
                this.s = s;
                this.in = s.getInputStream();
                start();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        @Override
        public void run() {
            byte[] b = new byte[1024];
            int readcount;
            try {
                while (true) {
                    readcount = in.read(b);
                    if (readcount == -1)
                        break;
                    System.out.println(StreamUtils.dumpMessage(b, 0, readcount));
                }
            }
            catch (IOException e) {
                System.out.println(e.getMessage());
            }
            
            try {
                if (s != null)
                    s.close();
            }
            catch (IOException e) {}
            
            System.out.println("Socket closed");
        }
    }
    
//    public static void main(String[] args) throws Exception {
//        SerialParameters serialParameters = new SerialParameters();
//        serialParameters.setCommPortId("COM1");
//        serialParameters.setPortOwnerName("Numb nuts");
//        serialParameters.setBaudRate(9600);
//        
//        ModbusFactory modbusFactory = new ModbusFactory();
//        
//        ModbusMaster master = modbusFactory.createRtuMaster(serialParameters, false);
//        System.out.println("init 1");
//        master.init();
//        System.out.println("destroy 1");
//        master.destroy();
//        
//        master = modbusFactory.createRtuMaster(serialParameters, false);
//        System.out.println("init 2");
//        master.init();
//        System.out.println("destroy 2");
//        master.destroy();
//    }
}


2 客户端

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.code.RegisterRange;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.NumericLocator;

public class Test {
    //    public static void main(String[] args) {
    //        NumericLocator l = new NumericLocator(0, 0, 0, DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED);
    //        System.out.println(l.bytesToValue(new byte[] { (byte) 0xE8, 0x03, 0x00, 0x00 }, 0));
    //    }

//    public static void main(String[] args) throws Exception {
//        {
//            ByteQueue b = new ByteQueue("01040000000271cb");
//            EncapMessageParser parser = new EncapMessageParser(false);
//            IncomingMessage m = parser.parseMessage(b);
//            System.out.println(m);
//        }
//        {
//            ByteQueue b = new ByteQueue("01040404d2162ed4f1");
//            EncapMessageParser parser = new EncapMessageParser(true);
//            IncomingMessage m = parser.parseMessage(b);
//            System.out.println(m);
//        }
//    }

        public static void main(String[] args) throws Exception {
            ModbusFactory factory = new ModbusFactory();
            IpParameters params = new IpParameters();
    
            //        params.setHost("127.0.0.1");
            //        params.setPort(502);
            //        params.setEncapsulated(true);
    
            params.setHost("10.1.10.10");
            params.setPort(12345);
            params.setEncapsulated(false);
    
            ModbusMaster master = factory.createTcpMaster(params, true);
            // master.setRetries(4);
            master.setTimeout(2000);
            master.setRetries(0);
    
            long start = System.currentTimeMillis();
            try {
                master.init();
                for (int i = 0; i < 100; i++) {
                    System.out.println(master.getValue(new NumericLocator(1, RegisterRange.HOLDING_REGISTER, 11,
                            DataType.TWO_BYTE_INT_SIGNED)));//参数信息(从机号、寄存器功能码、偏移地址、数据类型)
                }
            }
            finally {
                master.destroy();
            }
    
            System.out.println("Took: " + (System.currentTimeMillis() - start) + "ms");
        }

    // public static void main(String[] args) throws Exception {
    // ModbusFactory factory = new ModbusFactory();
    // IpParameters params = new IpParameters();
    // params.setHost("localhost");
    // params.setPort(12345);
    // ModbusMaster master = factory.createTcpMaster(params, true, false);
    // // master.setRetries(4);
    // master.setRetries(0);
    // try {
    // master.init();
    // master.getValue(1, RegisterRange.HOLDING_REGISTER, 0, DataType.TWO_BYTE_INT_UNSIGNED);
    // }
    // finally {
    // master.destroy();
    // }
    // }
}


猜你喜欢

转载自blog.csdn.net/zhaolei945/article/details/52623641