java modbus crc16校验码 socket给发送的数据添加crc校验码
首先crc16校验码的生成的原理在上一篇博客里面已经说过了;
前提:xframe配置京金华服务器的端口号,绑定ip地址和端口号
程序要实现什么?
这个程序主要实现的是服务器发送数据到客户端,然后客户端发送数据到服务器端;
是一问一答的形式;
只有服务器发送,客户端才会应答
发送的形式: 数据+两位校验码
代码如下:
package cn.com.project;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Bus {
public static void main(String[] args) {
try {
ServerSocket Server=new ServerSocket(6041);
StringBuilder ss=new StringBuilder();
//建立连接
Socket socket=Server.accept();
//发送数据
//获取输出流
OutputStream out=socket.getOutputStream();
DataOutputStream data=new DataOutputStream(out);
byte[] bb={45,00,03,00,07};
int [] s=Test.getCrc(bb);
byte [] bs=new byte[7];
bs[0]=0x2D;
bs[1]=0x00;
bs[2]=0x03;
bs[3]=0x00;
bs[4]=0x07;
bs[5]=(byte) s[0];
bs[6]=(byte) s[1];
data.write(bs);
data.flush();
//接受数据
InputStream in=socket.getInputStream();
byte[] by=new byte[1024];
byte[] buf=new byte[1024];
int len=in.read(by);
if(len>0){
for (int i = 0; i < len; i++) {
System.out.println("我尽量了");
int v=by[i] & 0xFF;
String hv=Integer.toHexString(v);
if(hv.length()<2){ss.append(0);}
ss.append(hv);
}
System.out.println(ss.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
校验添加校验码的程序如下:
package cn.com.project;
public class Test {
public static int [] getCrc(byte[] data) {
int flag;
// 16位寄存器,所有数位均为1
int wcrc = 0xffff;
for (int i = 0; i < data.length; i++) {
// 16 位寄存器的低位字节
// 取被校验串的一个字节与 16 位寄存器的高位字节进行“异或”运算
wcrc = wcrc ^ data[i];
for (int j = 0; j < 8; j++) {
flag = wcrc & 0x0001;
// 把这个 16 寄存器向右移一位
wcrc = wcrc >> 1;
// 若向右(标记位)移出的数位是 1,则生成多项式 1010 0000 0000 0001 和这个寄存器进行“异或”运算
if (flag == 1)
wcrc ^= 0xa001;
}
}
//获取低八位
int low=wcrc>>8;//或者wcrc/256
int up=wcrc%256;//获取高八位
int [] crc={up,low};
return crc;
/* return Integer.toHexString(wcrc);*/
}
}
发送以后接受成功的数据如下:
用串口助手和程序接受的数据都一样;
注意:网上许多关于java的添加crc16校验码都有误导的!!
如下:许多网上程序都有 int height=wcrc>>8;16位寄存器取高八位与每个字节“异或”,是不对的!
应该是16位寄存器取低八位与每个字节“”异或”