package com.flightfeather.uav.socket
|
|
import com.flightfeather.uav.socket.decoder.DataPackageDecoder
|
import io.netty.buffer.ByteBuf
|
import io.netty.channel.ChannelHandlerContext
|
import io.netty.handler.codec.ByteToMessageDecoder
|
|
/**
|
* @author riku
|
* Date: 2020/06/02
|
* 数据粘包分包解码器
|
*/
|
class UAVByteDataDecoder : ByteToMessageDecoder() {
|
|
companion object {
|
const val BASE_LENGTH = DataPackageDecoder.HEAD_BYTES + DataPackageDecoder.COMMAND_UNIT_BYTES +
|
DataPackageDecoder.DEVICE_CODE_BYTES + DataPackageDecoder.DATA_LENGTH + DataPackageDecoder.BCC_BYTES
|
const val HEAD1 = 0x01.toByte()
|
const val COMMAND_1 = 0x04.toByte()
|
const val COMMAND_2 = 0x05.toByte()
|
const val HEAD_LENGTH = DataPackageDecoder.HEAD_BYTES + DataPackageDecoder.COMMAND_UNIT_BYTES +
|
DataPackageDecoder.DEVICE_CODE_BYTES
|
}
|
|
override fun decode(p0: ChannelHandlerContext?, p1: ByteBuf?, p2: MutableList<Any>?) {
|
|
val dataList = mutableListOf<Byte>()
|
|
p1?.let {
|
// 可读长度必须大于基本长度
|
if (it.readableBytes() >= BASE_LENGTH) {
|
// 防止socket字节流攻击
|
// 防止,客户端传来的数据过大
|
if (it.readableBytes() > 2048) {
|
it.skipBytes(it.readableBytes())
|
}
|
// 记录包头开始的index
|
var beginReader = 0
|
|
while (true) {
|
// 获取包头开始的index
|
beginReader = it.readerIndex()
|
// 标记包头开始的index
|
it.markReaderIndex()
|
// 读到了协议的开始标志,结束while循环
|
val b = ByteArray(HEAD_LENGTH)
|
it.readBytes(b)
|
if (b[0] == HEAD1 &&
|
(b[1] == COMMAND_1 || b[1] == COMMAND_2)) {
|
b.forEach {b ->
|
dataList.add(b)
|
}
|
break
|
}
|
|
// 未读到包头,重置到之前记录的包头开始位置
|
// 略过1个字节后,再循环开始读取
|
it.resetReaderIndex()
|
it.readByte()
|
|
//当数据包长度不足时,立刻结束,等待后续数据到达
|
if (it.readableBytes() < BASE_LENGTH) {
|
return
|
}
|
}
|
|
// ByteArray(1).apply {
|
// it.readBytes(this)
|
// }.forEach {b ->
|
// dataList.add(b)
|
// }
|
|
//数据单元的长度
|
val length = getDataUnitLength(it, dataList)
|
// 判断请求数据单元数据及[LENGTH_BYTES]个字节的校验码是否到齐
|
if (it.readableBytes() < length + DataPackageDecoder.BCC_BYTES) {
|
// 还原读指针
|
it.readerIndex(beginReader)
|
return
|
}
|
|
//读取数据单元和校验码数据
|
ByteArray(length + DataPackageDecoder.BCC_BYTES).apply {
|
it.readBytes(this)
|
}.forEach {b ->
|
dataList.add(b)
|
}
|
|
p2?.add(dataList.toByteArray())
|
|
}
|
}
|
}
|
|
/**
|
* 获取数据单元长度并将其添加至结果列表中
|
*/
|
private fun getDataUnitLength(p1: ByteBuf, dataList: MutableList<Byte>): Int {
|
val sb = StringBuilder()
|
|
ByteArray(1).apply {
|
p1.readBytes(this)
|
}.forEach { b ->
|
val a: Int = if (b < 0) {
|
b + 256
|
} else {
|
b.toInt()
|
}
|
|
sb.append(a.toString(16))
|
|
dataList.add(b)
|
}
|
|
return sb.toString().toInt(16)
|
}
|
}
|