通信方式是socket,使用netty技术进行连接,客户端的数据类型是16进制;需要注意的地方:
1:读取16进制,我继承的是StringDecoder,在decode读取数据
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception { String HEXES = "0123456789ABCDEF"; byte[] req = new byte[msg.readableBytes()]; msg.readBytes(req); final StringBuilder hex = new StringBuilder(2 * req.length); for (int i = 0; i < req.length; i++) { byte b = req[i]; hex.append(HEXES.charAt((b & 0xF0) >> 4)) .append(HEXES.charAt((b & 0x0F))); } out.add(hex.toString()); }
2:在解析16进制数据的时候注意大小端问题,socket是对TCP/IP协议的封装,TCP/IP协议规定了在网络上必须采用网络字节顺序,也就是大端模式;而windows和linux是使用的小端模式,所以在读取的时候需要转化为小端模式读取,一个字节没问题,但是多个字节时需要转换;后面的字节放前面,倒序排放;同个网络和平台可能没关系,例如java虚拟机内部已经进行了处理,但是跨平台的话需要注意;
如:String msg = "00 BC 45";要先变成String str = "45 BC 00";
3:如果是16进制转10进制,需要考虑对方正负号的影响,如果是字节以FF开头,一定要注意是否要取反。不需要的话就没关系,需要的话就记得转换
if (sixteen.startsWith("FF")){ Long max = Long.parseLong("FFFFFFFF", 16); Long curLong = Long.parseLong(sixteen, 16); pos[i] = new Long(curLong - max).intValue(); }