1. 程式人生 > >java modbus crc16校驗碼 socket給傳送的資料新增crc校驗碼

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位暫存器取低八位與每個位元組“”異或”