1 Star 5 Fork 3

夏季的风 / TCP-UDP网络组件

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
DynamicReceiver.go 2.78 KB
一键复制 编辑 原始数据 按行查看 历史
lingbinbin 提交于 2021-08-17 20:33 . +加入JT1078分包算法
package Receivers
import (
"encoding/hex"
"errors"
"fmt"
"gitee.com/ling-bin/network/netInterface"
)
var (
maxLen = 65535 //允许最大包容量,超过会异常(网卡极限:64k)
)
//策略分包器
type DynamicReceiver struct {
currentReceiver netInterface.IReceiver //当前分包器
Receivers []netInterface.IReceiver //分包器集合
ReceiverLen int //分包器个数
IsPackStart bool //是否开始分包
IsSingle bool //是否只有一个分包算法
}
//策略分包器
func NewDynamicReceiver () *DynamicReceiver {
return &DynamicReceiver{
IsPackStart: false,
Receivers: nil,
}
}
//分包处理
func (d *DynamicReceiver) Receiver(conn netInterface.IConnection, buffer []byte) (err error) {
//1.查看有没有待分包数据
var newBuf []byte
cacheBf := conn.GetBytesCache()
if cacheBf.Len() != 0 {
cacheBf.Write(buffer)
newBuf = cacheBf.Bytes()
} else {
newBuf = buffer
}
//长度超长直接踢连接
if cacheBf.Len() > maxLen {
conn.Stop()
msg:=fmt.Sprint(" buffer out maxLen [", cacheBf.Len(), "]数据:",hex.EncodeToString(newBuf[:]))
cacheBf.Reset()
return errors.New(msg)
}
totalLen := len(newBuf)
startIndex := 0
skipCount := 0
for {
if startIndex == totalLen {
//刚好完成或未找到分包算法就清理缓存跳出函数
cacheBf.Reset()
if skipCount > 0 {
return errors.New(fmt.Sprint("查找分包算法跳过[", skipCount, "]字节完整数据:", hex.EncodeToString(newBuf[:])))
}
break
}
if d.IsPackStart { //确认当前包分包算法
iReceiver := d.selectReceiver(conn, newBuf[startIndex:])
if iReceiver == nil {
//后移一位查找分包算法
startIndex++
skipCount++
continue
}
d.currentReceiver = iReceiver
d.IsPackStart = false
}
//分包处理[内部也有可能跳过,需要具体分包算法处理]
bytes, handleIndex := d.currentReceiver.Receiver(conn, newBuf[startIndex:])
if len(bytes) == 0 {
if startIndex+handleIndex < totalLen {
//没有找到则重置缓存,重新设置缓存
cacheBf.Reset()
cacheBf.Write(newBuf[startIndex+handleIndex:])
}
break
}
//找到一包处理后继续找
conn.OnReceiveCompleted(bytes)
d.IsPackStart = true
startIndex += handleIndex
}
return nil
}
//选择分包器
func (d *DynamicReceiver) selectReceiver(conn netInterface.IConnection, buffer []byte) netInterface.IReceiver {
//单个分包算法直接跳过认包逻辑
if d.IsSingle {
isMe := d.Receivers[0].IsMeHandle(conn, buffer)
if isMe {
return d.Receivers[0]
}
return nil
}
//找到符合的分包器
for i := 0; i < d.ReceiverLen; i++ {
isMe := d.Receivers[i].IsMeHandle(conn, buffer)
if isMe {
return d.Receivers[i]
}
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/ling-bin/network.git
git@gitee.com:ling-bin/network.git
ling-bin
network
TCP-UDP网络组件
v1.5.5

搜索帮助

344bd9b3 5694891 D2dac590 5694891