项目场景:
对接丰海IF-KXB 系列led显示屏
问题描述:
把byte数组转成16进制字符串,通过网络调试工具测试可以上传显示信息。但是用代码跑就怎么都不通,一直卡在读取socket服务端返回信息的时候。
原因分析:
对接协议里明显写着每次请求服务端都会有返回消息,那么我拿不到返回消息的原因可能是发送就没成功
解决方案:
用抓取网络数据包,用ipTool工具(百度自行下载,网上有使用教程),注意不要用winshark抓包,winshark抓出来的包看不出问题所在。
第一张截图是用网络调试助手来发送时抓取的包,可以看到画圈的地方,是一个完整的数据包,02开头,03结尾。
第二张图是我用代码发送时抓取的包 ,可以看到数据包比第一张图少了点东西,没错,我是按照协议先写入0x02(起始符),在写数据体,最后写的结束符(0x03),不知道是不是因为这样才导致数据包分段发送。最后我把所有数据放到一个byte数组发送成功,代码贴在下面
public void sendMsg() {
initTcpIp();//创建socket连接,new Socket(ip,port);
byte[] by = null;
try {
by = INIT_TEXT.getBytes("GBK");//INIT_TEXT 大屏要显示的信息
ByteBufferBig buf1 = new ByteBufferBig();//大端模式 数据体
buf1.writeBytes(new byte[] { 00, 00 });// 地址
buf1.writeBytes(new byte[] { 49, 48 });// 帧类型
buf1.writeBytes(new byte[] { 112, 108, 97, 121, 46, 108, 115, 116 });// 文名 //(play.lst 的ascll码(112,108,97,121,46,108,115,116 )
buf1.writeBytes(new byte[] { 43 });// “+”的ascll
buf1.writeInt(0);// 文件偏移地址
buf1.writeBytes(by);// 文件数据
buf1.writeShort(CRC16Util.CRC_XModem(buf1.getBytes()));// crc16_Xmodem帧校验,校验的是起始符和结束符之间的数据,这块要注意!
buf1.writeBytes(new byte[] { 0x03 });//结束符
ByteBufferBig buf2 = new ByteBufferBig();//这里我new了一个大端,为了写入起始符
//这里 起始符 数据体 结束符 是一个完整的包,一起发送
buf2.writeBytes(new byte[] { 0x02 });//起始符
buf2.writeBytes(buf1.getBytes());//数据体
out.write(buf2.getBytes());// 结束符
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
byte[] rd = new byte[1];
ByteBufferBig byteBuf = new ByteBufferBig();
try {
while (in.read(rd) != -1) {
// 直接把获得的数据打印出来
byteBuf.writeBytes(rd);
if (rd[0] == 0x03)
break;
}
logger.info("【情报板显示】" + " 严禁超载 安全驾驶");
logger.info("服务器返回:" + Utils.bytesToHexString(byteBuf.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
close();//关闭输入、输出流,关闭socket
}
package com.ptxinke.led.utils;
import java.io.*;
/**
* 大端模式
*
*/
public final class ByteBufferBig implements Cloneable {
/** The read pos. */
private int readPos;
/** The write pos. */
private int writePos;
/** The data. */
private byte data[];
/**
* Position.
*
* @param i
* the i
*/
public void position(int i) {
readPos = writePos = i;
}
/**
* 写入固定位数的值,不够部分用0填充
* @param str
* @param length
*/
public void writeStringLength( String str, int length) {
byte[] tmp = str.trim().getBytes();
for (byte b : tmp) {
writeByte(b);
}
addByte( (byte) 0x00, length - tmp.length);
}
/**
* 用指定的值填充
* @param buf
* @param data
* @param size
*/
public void addByte(byte data, int size) {
for (int i = 0; i < size; i++) {
writeByte(data);
}
}
/**
* Read from.
*
* @param inputstream
* the inputstream
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public void readFrom(InputStream inputstream) throws IOException {
readFrom(inputstream, capacity() - length());
}
/**
* Skip bytes.
*
* @param i
* the i
*/
public void skipBytes(int i) {
readPos += i;
}
/**
* Read from.
*
* @param inputstream
* the inputstream
* @param i
* the i
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public void readFrom(InputStream inputstream, int i) throws IOException {
ensureCapacity(writePos + i);
for (int j = 0; j < i; j += inputstream.read(data, writePos + j, i - j))
;
writePos += i;
}
/**
* Capacity.
*
* @return the int
*/
public int capacity() {
return data.length;
}
/**
* Ensure capacity.
*
* @param i
* the i
*/
private void ensureCapacity(int i) {
if (i > data.length) {
byte abyte0[] = new byte[(i * 3) / 2];
System.arraycopy(data, 0, abyte0, 0, writePos);
data = abyte0;
}
}
/**
* Write to.
*
* @param outputstream
* the outputstream
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public void writeTo(OutputStream outputstream) throws IOException {
int i = available();
for (int j = 0; j < i; j++)
outputstream.write(data[readPos++]);
}
/**
* Pack.
*/
public void pack() {
if (readPos == 0)
return;
int i = available();
for (int j = 0; j < i; j++)
data[j] = data[readPos++];
readPos = 0;
writePos = i;
}
/**
* Write byte.
*
* @param i
* the i
*/
public void writeByte(int i) {
writeNumber(i, 1);
}
/**
* Read byte.
*
* @return the int
*/
public int readByte() {
return data[readPos++];
}
/**
* Read unsigned byte.
*
* @return the int
*/
public int readUnsignedByte() {
return data[readPos++] & 0xff;
}
/**
* Read.
*
* @param abyte0
* the abyte0
* @param i
* the i
* @param j
* the j
* @param k
* the k
*/
@SuppressWarnings("unused")
private void read(byte abyte0[], int i, int j, int k) {
System.arraycopy(data, k, abyte0, i, j);
}
/**
* Gets the read pos.
*
* @return the read pos
*/
public int getReadPos() {
return readPos;
}
/**
* Sets the read pos.
*
* @param i
* the new read pos
*/
public void setReadPos(int i) {
readPos = i;
}
/**
* Write.
*
* @param abyte0
* the abyte0
* @param i
* the i
* @param j
* the j
* @param k
* the k
*/
@SuppressWarnings("unused")
private void write(byte abyte0[], int i, int j, int k) {
ensureCapacity(k + j);
System.arraycopy(abyte0, i, data, k, j);
}
/**
* Write char.
*
* @param c
* the c
*/
public void writeChar(char c) {
writeNumber(c, 2);
}
/**
* Read char.
*
* @return the char
*/
public char readChar() {
return (char) (int) (readNumber(2) & 65535L);
}
/**
* Write number.
*
* @param value
* the l
* @param bit
* the i
*/
private void writeNumber(long value, int bit) {
ensureCapacity(writePos + bit);
// 低位在前
// for (int j = 0; j < bit; j++) {
// data[writePos++] = (byte) (int) value;
// value >>= 8;
// }
// 低位在前
// for (int i = 0; i < bit; i++) {
// data[writePos++] = (byte) (value >> 8 * i & 0x00000000000000ff);
// }
// 高位在前
for(int j = bit-1; j >=0; j--)
{
data[writePos++] = (byte)(value>>(8*j));
}
}
/**
* Read number. 每位数字 都进行与运算 按位与 0xff
*
* @param i
* the i
* @return the long
*/
private long readNumber(int i) {
long l = 0L;
// 低位在前
// for (int j = 0; j < i; j++) {
// long t = (long) (data[readPos++] & 0x00000000000000ff);
// t = t << j * 8;
// l = l | t;
// }
// 高位在前
for(int j = i-1; j >=0; j--){
long t = (long) (data[readPos++] & 0xff);
t = t << j*8;
l = l|t;
}
return l;
}
/**
* Gets the bytes.
*
* @return the bytes
*/
public byte[] getBytes() {
byte abyte0[] = new byte[length()];
System.arraycopy(data, 0, abyte0, 0, abyte0.length);
return abyte0;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#clone()
*/
public Object clone() {
ByteBufferBig bytebuffer = new ByteBufferBig(writePos);
System.arraycopy(data, 0, bytebuffer.data, 0, writePos);
bytebuffer.writePos = writePos;
bytebuffer.readPos = readPos;
return bytebuffer;
}
/**
* Write ansi string.
*
* @param s
* the s
*/
public void writeAnsiString(String s) {
if (s == null || s.length() == 0) {
writeShort(0);
} else {
if (s.length() > 32767)
throw new IllegalArgumentException("string over flow");
byte abyte0[] = s.getBytes();
writeShort(abyte0.length);
writeBytes(abyte0);
}
}
/**
* Read ansi string.
*
* @return the string
*/
public String readAnsiString() {
int i = readUnsignedShort();
if (i == 0) {
return "";
} else {
byte abyte0[] = readBytes(i);
return new String(abyte0);
}
}
/**
* Length.
*
* @return the int
*/
public int length() {
return writePos;
}
/**
* Write boolean.
*
* @param flag
* the flag
*/
public void writeBoolean(boolean flag) {
writeByte(flag ? 1 : 0);
}
/**
* Read boolean.
*
* @return true, if successful
*/
public boolean readBoolean() {
return readByte() != 0;
}
/**
* Read float.
*
* @return the float
*/
public float readFloat() {
int i = readInt();
return Float.intBitsToFloat(i);
}
/**
* Reset.
*/
public void reset() {
readPos = 0;
}
/**
* Write long.
*
* @param l
* the l
*/
public void writeLong(long l) {
writeNumber(l, 8);
}
public void writeLong(long l, int ma) {
writeNumber(l, 3);
}
/**
* Instantiates a new byte buffer.
*/
public ByteBufferBig() {
this(1024);
}
/**
* Instantiates a new byte buffer.
*
* @param i
* the i
*/
public ByteBufferBig(int i) {
data = new byte[i];
}
/**
* Instantiates a new byte buffer.
*
* @param abyte0
* the abyte0
*/
public ByteBufferBig(byte[] abyte0) {
this(abyte0, 0, abyte0.length);
}
/**
* Instantiates a new byte buffer.
*
* @param abyte0
* the abyte0
* @param i
* the i
* @param j
* the j
*/
public ByteBufferBig(byte abyte0[], int i, int j) {
data = abyte0;
readPos = i;
writePos = i + j;
}
/**
* Write short ansi string.
*
* @param s
* the s
*/
public void writeShortAnsiString(String s) {
if (s == null || s.length() == 0) {
writeByte(0);
} else {
byte abyte0[] = s.getBytes();
if (abyte0.length > 255)
throw new IllegalArgumentException("short string over flow");
writeByte(abyte0.length);
writeBytes(abyte0);
}
}
/**
* Read long.
*
* @return the long
*/
public long readLong() {
return readNumber(8);
}
public long readLong(int lo) {
return readNumber(lo);
}
/**
* Write short.
*
* @param i
* the i
*/
public void writeShort(int i) {
writeNumber(i, 2);
}
/**
* Read short.
*
* @return the int
*/
public int readShort() {
return (short) (int) (readNumber(2) & 65535L);
}
/**
* Write byte buffer.
*
* @param bytebuffer
* the bytebuffer
*/
public void writeByteBuffer(ByteBufferBig bytebuffer) {
writeByteBuffer(bytebuffer, bytebuffer.available());
}
/**
* Write byte buffer.
*
* @param bytebuffer
* the bytebuffer
* @param i
* the i
*/
public void writeByteBuffer(ByteBufferBig bytebuffer, int i) {
ensureCapacity(length() + i);
for (int j = 0; j < i; j++)
data[writePos++] = bytebuffer.data[bytebuffer.readPos++];
}
/**
* Write bytes.
*
* @param abyte0
* the abyte0
*/
public void writeBytes(byte abyte0[]) {
writeBytes(abyte0, 0, abyte0.length);
}
/**
* Write bytes.
*
* @param abyte0
* the abyte0
* @param i
* the i
* @param j
* the j
*/
public void writeBytes(byte abyte0[], int i, int j) {
ensureCapacity(writePos + j);
for (int k = 0; k < j; k++)
data[writePos++] = abyte0[i++];
}
/**
* Read bytes.
*
* @param i
* the i
* @return the byte[]
*/
public byte[] readBytes(int i) {
byte abyte0[] = new byte[i];
for (int j = 0; j < i; j++)
abyte0[j] = data[readPos++];
return abyte0;
}
/**
* 读取无符号short short.
*
* @return the int
*/
public int readUnsignedShort() {
return (int) (readNumber(2) & 65535L);
}
/**
* Read short ansi string.
*
* @return the string
*/
public String readShortAnsiString() {
int i = readUnsignedByte();
if (i == 0) {
return "";
} else {
byte abyte0[] = readBytes(i);
return new String(abyte0);
}
}
/**
* Available.
*
* @return the int
*/
public int available() {
return writePos - readPos;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer bu = new StringBuffer();
for (int i = 0; i < data.length && i < writePos; i++) {
bu.append(Integer.toHexString(data[i] & 0xff)).append(",");
}
return bu.toString();
}
/**
* Gets the write pos.
*
* @return the write pos
*/
public int getWritePos() {
return writePos;
}
/**
* Sets the write pos.
*
* @param i
* the new write pos
*/
public void setWritePos(int i) {
writePos = i;
}
/**
* Gets the raw bytes.
*
* @return the raw bytes
*/
public byte[] getRawBytes() {
return data;
}
/**
* Write utf.
*
* @param s
* the s
*/
public void writeUTF(String s) {
if (s == null)
s = "";
int length = s.length();
int j = 0;
for (int k = 0; k < length; k++) {
char c = s.charAt(k);
if (c < '\177')
j++;
else if (c > '\u07FF')
j += 3;
else
j += 2;
}
if (j > 65535)
throw new IllegalArgumentException("the string is too long:" + length);
ensureCapacity(writePos + j + 2);
writeShort(j);
for (int l = 0; l < length; l++) {
char c1 = s.charAt(l);
if (c1 < '\177')
data[writePos++] = (byte) c1;
else if (c1 > '\u07FF') {
data[writePos++] = (byte) (0xe0 | c1 >> 12 & 0xf);
data[writePos++] = (byte) (0x80 | c1 >> 6 & 0x3f);
data[writePos++] = (byte) (0x80 | c1 & 0x3f);
} else {
data[writePos++] = (byte) (0xc0 | c1 >> 6 & 0x1f);
data[writePos++] = (byte) (0x80 | c1 & 0x3f);
}
}
}
/**
* Read utf.
*
* @return the string
*/
public String readUTF() {
// int i = readUnsignedShort();
int i = readShort();
if (i == 0)
return "";
char ac[] = new char[i];
int j = 0;
for (int l = readPos + i; readPos < l;) {
int k = data[readPos++] & 0xff;
if (k < 127)
// 1
ac[j++] = (char) k;
else if (k >> 5 == 7) { // 3
byte byte0 = data[readPos++];
byte byte2 = data[readPos++];
ac[j++] = (char) ((k & 0xf) << 12 | (byte0 & 0x3f) << 6 | byte2 & 0x3f);
} else { // 2
byte byte1 = data[readPos++];
ac[j++] = (char) ((k & 0x1f) << 6 | byte1 & 0x3f);
}
}
return new String(ac, 0, j);
}
/**
* Clear.
*/
public void clear() {
writePos = readPos = 0;
}
/**
* Write int.
*
* @param i
* the i
*/
public void writeInt(int i) {
writeNumber(i, 4);
}
/**
* Read int.
*
* @return the int
*/
public int readInt() {
return (int) (readNumber(4) & -1L);
}
/**
* Position.
*
* @return the int
*/
public int position() {
return readPos;
}
// short类型转换byte[]
public byte[] shortToByteArray(short s, boolean littleEndian) { // littleEndian:true
// 高位在前
// false
// 低位在前
byte[] bytes = new byte[2];
for (int i = 0; i < 2; i++) {
int i1 = (littleEndian ? i : (1 - i)) << 3;
// int i1 = (littleEndian?i:(1-i))*8;
bytes[i] = (byte) ((s >> i1) & 0xff);
}
return bytes;
}
// int类型转换byte[]
public byte[] IntToByteArray(long l, boolean littleEndian) {
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
int i1 = (littleEndian ? i : (3 - i)) << 3;
bytes[i] = (byte) ((l >> i1) & 0xff);
}
return bytes;
}
// long类型转换byte[]
public byte[] longToByteArray(long l, boolean littleEndian) {
byte[] bytes = new byte[8];
for (int i = 0; i < 8; i++) {
int i1 = (littleEndian ? i : (7 - i)) << 3;
bytes[i] = (byte) ((l >> i1) & 0xff);
}
return bytes;
}
public static void main(String[] args) {
int i = 2018;
byte[] a = InttoByteArray(i);
for (int o = 0; o < a.length; o++) {
System.err.println(Integer.toHexString(a[o] & 0xff));
}
ByteBufferBig tmp = new ByteBufferBig();
tmp.writeInt(i);
System.err.println(tmp.toString());
System.err.println(tmp.readShort());
}
public static byte[] InttoByteArray(int n) {
byte[] b = new byte[4];
b[0] = (byte) (n & 0xff);
b[1] = (byte) (n >> 8 & 0xff);
b[2] = (byte) (n >> 16 & 0xff);
b[3] = (byte) (n >> 24 & 0xff);
return b;
}
}
//byte[] to HEXString byte转16进制字符串
public static final String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = String.format("%02x",(0xFF & bArray[i]));
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
sb.append(" ");
}
return sb.toString();
}