代码拉取完成,页面将自动刷新
// 数据的封包与拆包来解决数据的粘包问题
// 长度编码的传输方式:定长的消息头(header): 序列号和消息长度, 不定长的消息体(body)
// 客户端传入的是数字或字符串,封装成二进制数据包传递。另一端按规则拆解数据,获取指定长度取出相应的数据,转为字符串
// Buffer数据读写 writeInt16BE: 将value从指定位置写入
// 另外还有32BE的 readInt16BE: 从指定位置开始读取数据
class MyTransformCode {
constructor() {
this.packageHeaderLen = 4 // header总长度
this.serialNum = 0 // 序列号
this.serialLen = 2 // 序列号长度
}
// 编码
encode(data, serialNum) { // 数据,编号
const body = Buffer.from(data) // 把data变为二进制的数据
// 01 先按照指定的长度来申请一片内存空间做为 header 来使用
const headerBuf = Buffer.alloc(this.packageHeaderLen)
// 02
headerBuf.writeInt16BE(serialNum || this.serialNum) // 写入序列号,👇写入消息长度
headerBuf.writeInt16BE(body.length, this.serialLen) // 跳过之前写入继续写入,将数据长度做为消息长度
if (serialNum === undefined) {
this.serialNum++
}
return Buffer.concat([headerBuf, body])
}
// 解码
decode(buffer) {
const headerBuf = buffer.slice(0, this.packageHeaderLen)
const bodyBuf = buffer.slice(this.packageHeaderLen)
return {
serialNum: headerBuf.readInt16BE(),
bodyLength: headerBuf.readInt16BE(this.serialLen), // 跳过序列号长度读取
body: bodyBuf.toString()
}
}
// 获取包长度的方法
getPackageLen(buffer) {
if (buffer.length < this.packageHeaderLen) {
return 0
} else {
// 包里面还有数据可取
return this.packageHeaderLen + buffer.readInt16BE(this.serialLen) // header总长度 + 消息长度
}
}
}
module.exports = MyTransformCode
const ts = new MyTransformCode()
let str = '测试数据' // 12
let encodeBuf = ts.encode(str,1) // <Buffer 00 01 00 0c e6 b5 8b e8 af 95 e6 95 b0 e6 8d ae>
let a = ts.decode(encodeBuf) // { serialNum: 1, bodyLength: 12, body: '测试数据' }
let len = ts.getPackageLen(encodeBuf) // 16
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。