java对接丰海IF-KXB系列可变信息板

本文档记录了一次对接LED显示屏时遇到的问题,即使用Java代码发送数据包到服务端未成功,导致无法获取返回信息。通过抓包工具分析发现数据包被分段发送。解决方案是将起始符、数据体和结束符整合到一个byte数组中一次性发送,最终实现了数据正确传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

对接丰海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();
	}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值