java modbus crc16校驗碼 socket給傳送的資料新增crc校驗碼
阿新 • • 發佈:2018-11-01
首先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位暫存器取低八位與每個位元組“”異或”