一、自己总结
Modbus Tcp报文
byte[] bytes={00,00,00,00,00,06,05,03,00,72,00,02}; //查询的报文,数值10进制或16进制
06是指后面还有几位
05是电表上的设备地址(地址码)
03功能码(参考modbus协议)
00,72为起始位置(寄存器地址),即查询的属性是电压还是电流还是变比
00,02读取返回的数据位
二、别人总结的
例子:
package com.common.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Query {
public static float getValue(String host,int port,int deviceId,int begin,int end){
float value=0;
try {
byte[] bytes={00,00,00,00,00,06, (byte) deviceId,03, (byte) begin, (byte) end,00,02}; //查询的报文,数值直接10进制即可
Socket socket=new Socket(host,port); //建立socket
OutputStream outputStream=socket.getOutputStream(); //建立输出流
InputStream inputStream=socket.getInputStream(); //建立输入流
send(outputStream,bytes); //发送数据
value=accept(inputStream); //接收数据
outputStream.close();
inputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
//发送数据
private static void send(OutputStream outputStream,byte[] bytes){
try {
outputStream.write(bytes);
System.out.println("发送请求结束");
} catch (IOException e) {
e.printStackTrace();
}
}
//接收数据
private static float accept(InputStream inputStream){
float value=0;
try {
byte[] bytes = new byte[1024]; //接收的数据
byte[] valueBytes = new byte[1024]; //取数据位的数据
int length = inputStream.read(bytes); //数据长度
String hex= ""; //接收的数据,16进制
for (int i=0;i<length;i++) {
hex += String.format("%02X",bytes[i] & 0xFF); //转16进制
if(i>8){
valueBytes[i-9]=bytes[i];
}
}
value=getFloat(valueBytes,0); //转换成十进制读数
System.out.println("接收:"+hex);
System.out.println("长度:"+length);
System.out.println("读数:"+value);
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
// 从byte数组的index处的连续4个字节获得一个float
private static float getFloat(byte[] arr, int index) {
return Float.intBitsToFloat(getInt(arr, index));
}
// 从byte数组的index处的连续4个字节获得一个int
private static int getInt(byte[] arr, int index) {
return (0xff000000 & (arr[index+0] << 24)) |
(0x00ff0000 & (arr[index+1] << 16)) |
(0x0000ff00 & (arr[index+2] << 8)) |
(0x000000ff & arr[index+3]);
}
}
@Test
public void testSelectUser() throws Exception{
float value=Query.getValue("10.112.33.253",16002,05,00,46);
System.out.println("回传数值:"+value);
}