1 Star 0 Fork 0

35819194@qq.com/go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
defmsghead.go 4.25 KB
一键复制 编辑 原始数据 按行查看 历史
35819194@qq.com 提交于 2024-04-24 11:02 . 修改 文件名
package socks
import (
"fmt"
"io"
)
const (
cDefaultHeaderSign = uint32(0xABCDEF99) // 默认头部标识
cDefaultHeaderSize = 12
cDefaultBuffSize = 1024 * 8
)
type IMsgHeader interface {
GetHeaderSize() int
ReadHeader(br *BufferUtils) (isOk bool, bodyLen int)
WriteHeader(bw *BufferUtils, bodyLen int) bool
}
type IHeaderCreator interface {
CreateMsgHeader() IMsgHeader
}
type DefaultMsgHead struct {
signature uint32
bodyLen uint32
Cmd uint32
}
func (d *DefaultMsgHead) GetHeaderSize() int {
return cDefaultHeaderSize
}
func (d *DefaultMsgHead) ReadHeader(br *BufferUtils) (isOk bool, bodyLen int) {
isOk = false
bodyLen = 0
if br.GetRemainLen() >= d.GetHeaderSize() {
s := br.ReadUint32()
if s == cDefaultHeaderSign {
d.signature = s
d.bodyLen = br.ReadUint32()
d.Cmd = br.ReadUint32()
isOk = true
bodyLen = int(d.bodyLen)
}
}
return isOk, bodyLen
}
func (d *DefaultMsgHead) WriteHeader(bw *BufferUtils, bodyLen int) bool {
ret := false
if bw.GetRemainLen() >= d.GetHeaderSize() {
d.bodyLen = uint32(bodyLen)
bw.Write(d.signature)
bw.Write(d.bodyLen)
bw.Write(d.Cmd)
ret = true
} else {
show_log("size is too small:", bw.GetDataLen(), d.GetHeaderSize(), "remain = ", bw.GetRemainLen(), bw.pos)
}
return ret
}
func (d *DefaultMsgHead) CreateMsgHeader() IMsgHeader {
return &DefaultMsgHead{signature: cDefaultHeaderSign}
}
type DefaultHeadHandler struct {
head IMsgHeader
headIsOk bool
body []byte
bodyLen int
bodyWriteLen int
buff []byte
dataLen int
offset int
br *BufferUtils // 读缓冲区
writeHead IMsgHeader // 发送时需要的头部
bw *BufferUtils // 写缓冲区
headerCreater IHeaderCreator
}
func NewDefaultHeadHandler(creater IHeaderCreator) *DefaultHeadHandler {
if creater == nil {
creater = &DefaultMsgHead{}
}
ret := &DefaultHeadHandler{head: creater.CreateMsgHeader(), headIsOk: false,
buff: make([]byte, cDefaultBuffSize), br: NewBufferUtils(nil),
headerCreater: creater, bw: NewBufferUtils(nil), writeHead: creater.CreateMsgHeader(),
}
ret.bw.ResetBuffSize(ret.head.GetHeaderSize())
return ret
}
func (d *DefaultHeadHandler) resetBuffOffset() {
if d.dataLen > 0 {
copy(d.buff[d.offset:d.offset+d.dataLen], d.buff)
}
d.offset = 0
}
func (d *DefaultHeadHandler) ReadPack(reader io.Reader, conn SocketConnection) (pack *PackData) { // 判断包头是否合法,包头是否完整,并返回头部信息 // 不成功 readLen = 0
br := d.br
pack = nil
for {
br.Reset(d.buff[d.offset : d.offset+d.dataLen])
if !d.headIsOk { // 头部还未接收完成
if br.GetRemainLen() >= d.head.GetHeaderSize() {
p := br.GetPos()
if d.headIsOk, d.bodyLen = d.head.ReadHeader(br); d.headIsOk {
d.body = make([]byte, d.bodyLen)
d.bodyWriteLen = 0
} else {
br.ResetPos(p + 1) // 前移一个字节,继续试探
}
} else {
readlen, err := reader.Read(d.buff[d.offset:])
if err != nil {
fmt.Println("socket read error: ", err)
return nil // 接收出错,直接返回空,断开连接
}
d.dataLen += readlen // 头部的长度不够
}
} else if d.bodyWriteLen < d.bodyLen {
if br.GetRemainLen() > 0 {
n := br.ReadBuffer(d.body[d.bodyWriteLen:])
d.bodyWriteLen += n
} else {
readlen, err := reader.Read(d.body[d.bodyWriteLen:])
if err != nil {
return nil
}
d.bodyWriteLen += readlen
}
}
p := br.GetPos()
if p > 0 {
d.offset += p
d.dataLen -= p
if d.dataLen > 0 {
if d.offset > cDefaultBuffSize/2 {
d.resetBuffOffset()
}
} else { // 没有数据了,从头开始
d.offset = 0
}
}
if (d.bodyWriteLen >= d.bodyLen) && d.headIsOk {
pack = &PackData{d.head, d.body}
d.head = d.headerCreater.CreateMsgHeader()
d.body = nil
d.headIsOk = false
break
}
}
return pack
}
func (d *DefaultHeadHandler) WritePack(writer io.Writer, datas []byte) bool { // 写入包头信息
bw := d.bw
bw.ResetPos(0)
dataLen := len(datas)
if d.writeHead.WriteHeader(bw, dataLen) {
if writeBuffer(writer, bw.bits) {
if (dataLen == 0) || writeBuffer(writer, datas) {
return true
}
} else {
show_log("writeBuffer failed!!!")
}
} else {
show_log("WritePack failed!!!")
}
return false
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/cjianwen/go.git
git@gitee.com:cjianwen/go.git
cjianwen
go
go
v1.0.5

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385