背景:做了个智能柜管理系统,需要和智能柜对接。交互使用的是socket。
转换逻辑:
发送规则:数据(1)---->16进制(0x01)---->高4位(0x00)、低四位(0x01)---->10进制(0、1)---->ansi码(48,49)---->16进制(0x30,0x31)---->发送
ansi如图
发送接收数据:start为码头,end为码尾加验证。是和第三方沟通的标志。
/**
* 发送指令
* @param ip 智能柜ip地址
* @param com 指令类型
* @param data 数据
* @return
*/
public static String sendSocket(String ip,byte[] com,byte[] data){
try{
Socket socket = new Socket(ip,port);
//获取一个输出流,向服务端发送信息
OutputStream outputStream=socket.getOutputStream();
outputStream.write(start);
outputStream.write(com);
if(data!=null){
outputStream.write(data);
}
outputStream.write(end);
socket.shutdownOutput();
//获取一个输入流,接收服务端的信息
InputStream inputStream=socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
DataInputStream dis = new DataInputStream(bis);
byte[] bytes = new byte[1];
String ret = "";
byte[] result = new byte[1024];
int i = 0;
while (dis.read(bytes) != -1) {
ret += bytesToHexString(bytes) + " ";
result[1] = bytes[0];
}
System.out.println(ret);
//关闭相对应的资源
dis.close();
inputStream.close();
outputStream.close();
socket.close();
return ret;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* 将接收到的数据转换为16进制
* @param bytes
* @return
*/
public static String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
步骤:传递一个数后获取高4位height,低4位low。在根据ansi数组获取值
/**
* 0-f 0x30,0x46
*/
public static byte[] ansi = new byte[]{0x30,0x31,0x32,0x33,0x34,
0x35,0x36,0x37,0x38,0x39,
0x41,0x42,0x43,0x44,0x45,0x46};
/**
* 将一个integer值转换成两个0xXX的字符串。integer要小于255.
* @param code
* @return
*/
public static byte[] transfer(Integer code){
if(code==null){
return null;
}
int height = ((code & 0xf0) >> 4);
int low = (code & 0x0f);
byte[] b = new byte[2];
b[0] = ansi[height];
b[1] = ansi[low];
return b;
}
接收数据:33 32----> 3,2 ---->0x32 ---->2
private static final String HexStr = "0123456789abcdef";
private static Map getMap(){
if(map.isEmpty()){
for(int i=0;i<16;i++){
if(i<=9){
map.put(i+30+"",HexStr.substring(i,i+1));
}else{
map.put(i+31+"",HexStr.substring(i,i+1));
}
}
}
return map;
}
将获取到的数据(33 32)按照空格分开
String[] str = res.split(" ");
两两合并生成byte数组。
byte[] b = new byte[17]; for(int i=0;i<17;i++){ int height = HexStr.indexOf(map1.get(str[i*2])); int low = HexStr.indexOf(map1.get(str[i*2+1])); b[i] = (byte) (height<<4|low); }
业务需要,一个byte位代表8个箱门状态,0-开,1-关
MapgoodsMap = new HashMap<>(); goodsMap.put("1",(b&0x01)==0x01?1:0); goodsMap.put("2",(b&0x02)==0x02?1:0); goodsMap.put("3",(b&0x04)==0x04?1:0); goodsMap.put("4",(b&0x08)==0x08?1:0); goodsMap.put("5",(b&0x10)==0x10?1:0); goodsMap.put("6",(b&0x20)==0x20?1:0); goodsMap.put("7",(b&0x40)==0x40?1:0); goodsMap.put("8",(b&0x80)==0x80?1:0);