Programing/Network

JAVA TCP통신 CRC-16 구하는 방법, CRC-16 체크

리커니 2016. 11. 3.
반응형

 

JAVA TCP통신 CRC-16 구하는 방법, CRC-16 체크

 

( byte[2]형 16bit CRC )

 

장비 제어를 하다보면 프로토콜에 CRC-16 값이 포함된 경우가 많다.

이는 Check Sum 과 같은 방식보다 신뢰도가 높은 에러 검출 방법이기 때문이다.

 

그럼 Java 로 CRC-16 값을 구하는 방법을 알아보자.

 

CRC-16을 구하기 위해서는 우선 256개로 구성된 배열이 필요하다.

아래 txt 파일의 소스 참조.

 

crc-16 table.txt

 

==================TCP통신=====================

 

이제 소켓통신을 위한 준비를 해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
String ip = 전송할 대상의 ip
 
String port = 전송할 대상의 포트
 
//소켓을 생성하여 연결 요쳥
 
Socket socket = new Socket(ip, port);
 
//데이터를 전송할 outputStream 생성
 
OutputStream os = socket.getOutputStream();
 
//바이너리 값을 전송하기 위해 DataOutputStream 생성
 
DataOutputStream dos = new DataOutputStream(os);
 
try {
     //바이트 배열을 만들어 전송
 
dos.write(makeByteData(ctl));
dos.flush();
 
finally {
    dos.close();
    socket.close();
}
cs

 

 

==================전송할 byte데이터 생성=====================

받아온 스트링 변수에 따라 전송할 바이트 값을 구한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public static byte[] makeByteData(String ctl){
     byte[] data = new byte[11];
  /*DLE*/
  data[0= (byte)0x10;
  /*STX*/
  data[1= (byte)0x02;
  /*MCUADDR*/
  data[2= (byte)0x01;
  /*OPCODE*/
  data[3= (byte)0x11;
  //parameter 1 control on/off
  data[4= (byte)0x01
  .......생략
 
  .......
/*DLE*/
   data[8= (byte)0x10;
   /*ETX*/
   data[9= (byte)0x03;
 
 
   /*crc16을 구하기 위한 바이트 데이터 생성*/
 
   /*crc16은 3~8번째 바이트 배열 값으로 구한다.*/
   byte[] crc = new byte[6];
   crc[0= data[2];
   crc[1= data[3];
   crc[2= data[4];
   crc[3= data[5];
   crc[4= data[6];
   crc[5= data[7];
   /*구한 crc16을 제어 바이트 변수에 대입*/
   byte[] crc16byte = fn_makeCRC16(crc);
   data[10= crc16byte[1];
   data[11= crc16byte[0];
  }
  return data;
 
}
 
public static byte[] fn_makeCRC16(byte[] bytes){
  
 
//위의 txt 파일에 있는 값을 소스상에 붙여넣기 하고 해당값을 가져온다.
  int[] CRC = CRCTable();
  int icrc = 0x00;
     for (byte b : bytes) {
            icrc = (icrc >>> 8) ^ CRC[(icrc ^ b) & 0xff];
        }
  System.out.println("Integer " + Integer.toHexString(icrc)); // test   나와야되는 값 
  return fnShortToBytes((short)icrc,0);//HtypeCast의 short를 byte로 변환해주는 함수
}
 
//short 값을 바이트 배열로 변환
public static byte[] fnShortToBytes(short Value, int Order){
    byte[] temp;
    temp = new byte[]{ (byte)((Value & 0xFF00>> 8), (byte)(Value & 0x00FF) };
    temp = fnChangeByteOrder(temp,Order);
    return temp;
}
 
//상 하위 변환
private static byte[] fnChangeByteOrder(byte[] value,int Order){
    int idx = value.length;
    byte[] Temp = new byte[idx];
 
    if(Order == 1){
        Temp = value;
    }else if(Order == 0){
        for(int i=0;i<idx;i++) {
            Temp[i] = value[idx-(i+1)];
        }
    }
    return Temp;
}
 
 
cs
반응형

댓글

💲 추천 글