|
@@ -24,9 +24,10 @@ const MAX_LENGTH = 0xFFFF
|
|
const MAX2_LENGTH = 0x1FFFFFFF // 500 M,避免申请过大内存
|
|
const MAX2_LENGTH = 0x1FFFFFFF // 500 M,避免申请过大内存
|
|
|
|
|
|
type Tcp2 struct {
|
|
type Tcp2 struct {
|
|
- cf *config.Config
|
|
|
|
- conn net.Conn
|
|
|
|
- cipher *util.Cipher // 记录当前的加解密类
|
|
|
|
|
|
+ cf *config.Config
|
|
|
|
+ conn net.Conn
|
|
|
|
+ cipher *util.Cipher // 记录当前的加解密类
|
|
|
|
+ compress bool // 是否启用压缩
|
|
}
|
|
}
|
|
|
|
|
|
// 服务端
|
|
// 服务端
|
|
@@ -186,9 +187,10 @@ func Dial(cf *config.Config, addr string, hash string) (conn.Connect, error) {
|
|
}
|
|
}
|
|
// 初始化
|
|
// 初始化
|
|
c := &Tcp2{
|
|
c := &Tcp2{
|
|
- cf: cf,
|
|
|
|
- conn: conn,
|
|
|
|
- cipher: cipher,
|
|
|
|
|
|
+ cf: cf,
|
|
|
|
+ conn: conn,
|
|
|
|
+ cipher: cipher,
|
|
|
|
+ compress: true,
|
|
}
|
|
}
|
|
return c, nil
|
|
return c, nil
|
|
}
|
|
}
|
|
@@ -244,8 +246,8 @@ func (c *Tcp2) WriteAuthInfo(channel string, auth []byte) (err error) {
|
|
if channelLen > 0xFFFF {
|
|
if channelLen > 0xFFFF {
|
|
return errors.New("length of channel over")
|
|
return errors.New("length of channel over")
|
|
}
|
|
}
|
|
- // id(uint16)+proto(string)+version(uint8)+channel(string)+auth([]byte)
|
|
|
|
- dlen := 2 + 1 + protoLen + 1 + 2 + channelLen + len(auth)
|
|
|
|
|
|
+ // id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
|
|
|
|
+ dlen := 2 + 1 + protoLen + 1 + 1 + 2 + channelLen + len(auth)
|
|
|
|
|
|
buf, start := c.writeDataLen(dlen)
|
|
buf, start := c.writeDataLen(dlen)
|
|
index := start
|
|
index := start
|
|
@@ -260,6 +262,13 @@ func (c *Tcp2) WriteAuthInfo(channel string, auth []byte) (err error) {
|
|
buf[index] = VERSION
|
|
buf[index] = VERSION
|
|
index++
|
|
index++
|
|
|
|
|
|
|
|
+ if c.compress {
|
|
|
|
+ buf[index] = 0x01
|
|
|
|
+ } else {
|
|
|
|
+ buf[index] = 0
|
|
|
|
+ }
|
|
|
|
+ index++
|
|
|
|
+
|
|
binary.BigEndian.PutUint16(buf[index:index+2], uint16(channelLen))
|
|
binary.BigEndian.PutUint16(buf[index:index+2], uint16(channelLen))
|
|
index += 2
|
|
index += 2
|
|
|
|
|
|
@@ -322,7 +331,7 @@ func (c *Tcp2) readMessage(deadline int) ([]byte, error) {
|
|
}
|
|
}
|
|
|
|
|
|
// 获取Auth信息
|
|
// 获取Auth信息
|
|
-// id(uint16)+proto(string)+version(uint8)+channel(string)+auth([]byte)
|
|
|
|
|
|
+// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
|
|
func (c *Tcp2) ReadAuthInfo() (proto string, version uint8, channel string, auth []byte, err error) {
|
|
func (c *Tcp2) ReadAuthInfo() (proto string, version uint8, channel string, auth []byte, err error) {
|
|
defer func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
if r := recover(); r != nil {
|
|
@@ -335,48 +344,51 @@ func (c *Tcp2) ReadAuthInfo() (proto string, version uint8, channel string, auth
|
|
return
|
|
return
|
|
}
|
|
}
|
|
msgLen := len(msg)
|
|
msgLen := len(msg)
|
|
- if msgLen < 4 {
|
|
|
|
- err = errors.New("message length less than 4")
|
|
|
|
|
|
+ if msgLen < 9 {
|
|
|
|
+ err = errors.New("wrong message length")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start := 0
|
|
|
|
- id := binary.BigEndian.Uint16(msg[start : start+2])
|
|
|
|
|
|
+ index := 0
|
|
|
|
+ id := binary.BigEndian.Uint16(msg[index : index+2])
|
|
if id != config.ID_AUTH {
|
|
if id != config.ID_AUTH {
|
|
err = fmt.Errorf("wrong message id: %d", id)
|
|
err = fmt.Errorf("wrong message id: %d", id)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start += 2
|
|
|
|
|
|
+ index += 2
|
|
|
|
|
|
- protoLen := int(msg[start])
|
|
|
|
|
|
+ protoLen := int(msg[index])
|
|
if protoLen < 2 {
|
|
if protoLen < 2 {
|
|
err = errors.New("wrong proto length")
|
|
err = errors.New("wrong proto length")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start++
|
|
|
|
- proto = string(msg[start : start+protoLen])
|
|
|
|
|
|
+ index++
|
|
|
|
+ proto = string(msg[index : index+protoLen])
|
|
if proto != PROTO {
|
|
if proto != PROTO {
|
|
err = fmt.Errorf("wrong proto: %s", proto)
|
|
err = fmt.Errorf("wrong proto: %s", proto)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start += protoLen
|
|
|
|
|
|
+ index += protoLen
|
|
|
|
|
|
- version = msg[start]
|
|
|
|
|
|
+ version = msg[index]
|
|
if version != VERSION {
|
|
if version != VERSION {
|
|
err = fmt.Errorf("require version %d, get version: %d", VERSION, version)
|
|
err = fmt.Errorf("require version %d, get version: %d", VERSION, version)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start++
|
|
|
|
|
|
+ index++
|
|
|
|
+
|
|
|
|
+ c.compress = (msg[index] & 0x01) != 0
|
|
|
|
+ index++
|
|
|
|
|
|
- channelLen := int(binary.BigEndian.Uint16(msg[start : start+2]))
|
|
|
|
|
|
+ channelLen := int(binary.BigEndian.Uint16(msg[index : index+2]))
|
|
if channelLen < 2 {
|
|
if channelLen < 2 {
|
|
err = errors.New("wrong channel length")
|
|
err = errors.New("wrong channel length")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- start += 2
|
|
|
|
- channel = string(msg[start : start+channelLen])
|
|
|
|
- start += channelLen
|
|
|
|
|
|
+ index += 2
|
|
|
|
+ channel = string(msg[index : index+channelLen])
|
|
|
|
+ index += channelLen
|
|
|
|
|
|
- auth = msg[start:]
|
|
|
|
|
|
+ auth = msg[index:]
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
@@ -387,33 +399,83 @@ func (c *Tcp2) WriteRequest(id uint16, cmd string, data []byte) error {
|
|
if cmdLen > 0x7F {
|
|
if cmdLen > 0x7F {
|
|
return errors.New("command length is more than 0x7F")
|
|
return errors.New("command length is more than 0x7F")
|
|
}
|
|
}
|
|
- dlen := 2 + 1 + cmdLen + len(data)
|
|
|
|
- buf, start := c.writeDataLen(dlen)
|
|
|
|
- index := start
|
|
|
|
- binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
- index += 2
|
|
|
|
- buf[index] = byte(cmdLen)
|
|
|
|
- index++
|
|
|
|
- copy(buf[index:index+cmdLen], cmd)
|
|
|
|
- index += cmdLen
|
|
|
|
- copy(buf[index:], data)
|
|
|
|
- buf[start+dlen] = util.CRC8(buf[start : start+dlen])
|
|
|
|
- return c.writeMessage(buf)
|
|
|
|
|
|
+ dlen := len(data)
|
|
|
|
+ if c.compress && dlen > 0 {
|
|
|
|
+ compressedData, ok := util.CompressData(data)
|
|
|
|
+ ddlen := 2 + 1 + cmdLen + 1 + len(compressedData)
|
|
|
|
+ buf, start := c.writeDataLen(ddlen)
|
|
|
|
+ index := start
|
|
|
|
+ binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
+ index += 2
|
|
|
|
+
|
|
|
|
+ buf[index] = byte(cmdLen)
|
|
|
|
+ index++
|
|
|
|
+ copy(buf[index:index+cmdLen], cmd)
|
|
|
|
+ index += cmdLen
|
|
|
|
+
|
|
|
|
+ if ok {
|
|
|
|
+ buf[index] = 0x01
|
|
|
|
+ } else {
|
|
|
|
+ buf[index] = 0
|
|
|
|
+ }
|
|
|
|
+ index++
|
|
|
|
+
|
|
|
|
+ copy(buf[index:], compressedData)
|
|
|
|
+ buf[start+ddlen] = util.CRC8(buf[start : start+ddlen])
|
|
|
|
+ return c.writeMessage(buf)
|
|
|
|
+ } else {
|
|
|
|
+ ddlen := 2 + 1 + cmdLen + dlen
|
|
|
|
+ buf, start := c.writeDataLen(ddlen)
|
|
|
|
+ index := start
|
|
|
|
+ binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
+ index += 2
|
|
|
|
+ buf[index] = byte(cmdLen)
|
|
|
|
+ index++
|
|
|
|
+ copy(buf[index:index+cmdLen], cmd)
|
|
|
|
+ index += cmdLen
|
|
|
|
+ copy(buf[index:], data)
|
|
|
|
+ buf[start+ddlen] = util.CRC8(buf[start : start+ddlen])
|
|
|
|
+ return c.writeMessage(buf)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// 发送响应数据包到网络
|
|
// 发送响应数据包到网络
|
|
// 网络格式:[id, stateCode, data]
|
|
// 网络格式:[id, stateCode, data]
|
|
func (c *Tcp2) WriteResponse(id uint16, state uint8, data []byte) error {
|
|
func (c *Tcp2) WriteResponse(id uint16, state uint8, data []byte) error {
|
|
- dlen := 2 + 1 + len(data)
|
|
|
|
- buf, start := c.writeDataLen(dlen)
|
|
|
|
- index := start
|
|
|
|
- binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
- index += 2
|
|
|
|
- buf[index] = state | 0x80
|
|
|
|
- index++
|
|
|
|
- copy(buf[index:], data)
|
|
|
|
- buf[start+dlen] = util.CRC8(buf[start : start+dlen])
|
|
|
|
- return c.writeMessage(buf)
|
|
|
|
|
|
+ dlen := len(data)
|
|
|
|
+ if c.compress && dlen > 0 {
|
|
|
|
+ compressedData, ok := util.CompressData(data)
|
|
|
|
+ ddlen := 2 + 1 + 1 + len(compressedData)
|
|
|
|
+ buf, start := c.writeDataLen(ddlen)
|
|
|
|
+ index := start
|
|
|
|
+ binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
+ index += 2
|
|
|
|
+
|
|
|
|
+ buf[index] = state | 0x80
|
|
|
|
+ index++
|
|
|
|
+
|
|
|
|
+ if ok {
|
|
|
|
+ buf[index] = 0x001
|
|
|
|
+ } else {
|
|
|
|
+ buf[index] = 0
|
|
|
|
+ }
|
|
|
|
+ index++
|
|
|
|
+
|
|
|
|
+ copy(buf[index:], compressedData)
|
|
|
|
+ buf[start+ddlen] = util.CRC8(buf[start : start+ddlen])
|
|
|
|
+ return c.writeMessage(buf)
|
|
|
|
+ } else {
|
|
|
|
+ ddlen := 2 + 1 + len(data)
|
|
|
|
+ buf, start := c.writeDataLen(ddlen)
|
|
|
|
+ index := start
|
|
|
|
+ binary.BigEndian.PutUint16(buf[index:index+2], id)
|
|
|
|
+ index += 2
|
|
|
|
+ buf[index] = state | 0x80
|
|
|
|
+ index++
|
|
|
|
+ copy(buf[index:], data)
|
|
|
|
+ buf[start+ddlen] = util.CRC8(buf[start : start+ddlen])
|
|
|
|
+ return c.writeMessage(buf)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// 发送ping包
|
|
// 发送ping包
|
|
@@ -453,14 +515,16 @@ func (c *Tcp2) ReadMessage(deadline int) (msgType conn.MsgType, id uint16, cmd s
|
|
cmdLen := int(cmdx)
|
|
cmdLen := int(cmdx)
|
|
cmd = string(msg[3 : cmdLen+3])
|
|
cmd = string(msg[3 : cmdLen+3])
|
|
data = msg[cmdLen+3:]
|
|
data = msg[cmdLen+3:]
|
|
- return
|
|
|
|
} else {
|
|
} else {
|
|
// 响应数据包
|
|
// 响应数据包
|
|
msgType = conn.ResponseMsg
|
|
msgType = conn.ResponseMsg
|
|
state = cmdx & 0x7F
|
|
state = cmdx & 0x7F
|
|
data = msg[3:]
|
|
data = msg[3:]
|
|
- return
|
|
|
|
}
|
|
}
|
|
|
|
+ if c.compress && len(data) > 1 {
|
|
|
|
+ data, _ = util.UncompressData(data)
|
|
|
|
+ }
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
|
|
// 获取远程的地址
|
|
// 获取远程的地址
|