```
fix(socket): 修复TCP连接处理逻辑与数据包解析问题 - 在 `ServerEvent.go` 中,移除无效的错误连接计数逻辑,明确标识 TCP 连接并直接调用 `handleTcp` - 优化 `handleTcp` 方法中对数据解析
This commit is contained in:
@@ -119,10 +119,8 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) {
|
||||
return action
|
||||
}
|
||||
if !ok { //升级失败,说明是tcp连接
|
||||
// if c.Context().(*player.ClientData).ERROR_CONNUT > 5 {
|
||||
// return gnet.Close
|
||||
// }
|
||||
// c.Context().(*player.ClientData).ERROR_CONNUT += 1
|
||||
ws.Tcp = true
|
||||
|
||||
return s.handleTcp(c)
|
||||
|
||||
}
|
||||
@@ -159,6 +157,7 @@ func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) {
|
||||
if err != nil {
|
||||
if err != codec.ErrIncompletePacket {
|
||||
action = gnet.Close
|
||||
return
|
||||
} else {
|
||||
if err := conn.Wake(nil); err != nil { // wake up the connection manually to avoid missing the leftover data
|
||||
logging.Errorf("failed to wake up the connection, %v", err)
|
||||
@@ -168,10 +167,12 @@ func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) {
|
||||
|
||||
}
|
||||
|
||||
//client := conn.RemoteAddr().String()
|
||||
_ = s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复
|
||||
s.parser(conn, data)
|
||||
})
|
||||
if data != nil {
|
||||
//client := conn.RemoteAddr().String()
|
||||
_ = s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复
|
||||
s.parser(conn, data)
|
||||
})
|
||||
}
|
||||
|
||||
return action
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
var ErrIncompletePacket = errors.New("incomplete packet")
|
||||
|
||||
const maxBodyLen = 10 * 1024 * 1024 // 业务最大包体长度,按需调整
|
||||
// TomeeSocketCodec 协议格式:
|
||||
//
|
||||
// * 0 4
|
||||
@@ -44,9 +45,9 @@ func (codec TomeeSocketCodec) Encode(buf []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
|
||||
const maxBodyLen = 10 * 1024 * 1024 // 业务最大包体长度,按需调整
|
||||
|
||||
// 1. 读取4字节长度头
|
||||
// handle(c)
|
||||
// 先读取4字节的包长度
|
||||
lenBuf, err := c.Peek(4)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.ErrShortBuffer) {
|
||||
@@ -55,15 +56,14 @@ func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 2. 解析长度并校验上限
|
||||
bodyLen := binary.BigEndian.Uint32(lenBuf)
|
||||
if bodyLen > maxBodyLen {
|
||||
return nil, errors.New("packet body exceeds max length")
|
||||
}
|
||||
totalLen := 4 + int(bodyLen) // 总包长=长度头(4)+包体
|
||||
totalLen := 4 + int(bodyLen)
|
||||
|
||||
// 3. 检查整个包是否完整(关键修复:用totalLen判断)
|
||||
fullBuf, err := c.Peek(totalLen)
|
||||
// 检查整个包是否完整
|
||||
buf, err := c.Peek(int(bodyLen))
|
||||
if err != nil {
|
||||
if errors.Is(err, io.ErrShortBuffer) {
|
||||
return nil, ErrIncompletePacket
|
||||
@@ -71,15 +71,12 @@ func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 4. 提取包体(关键修复:跳过前4字节长度头)
|
||||
// 提取包体
|
||||
body := make([]byte, bodyLen)
|
||||
copy(body, fullBuf[4:]) // 从fullBuf[4:]开始拷贝,仅取包体
|
||||
copy(body, buf)
|
||||
|
||||
// 5. 丢弃已解析的完整数据
|
||||
_, err = c.Discard(totalLen) // 原代码用_忽略err,建议处理(可选)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 从缓冲区中丢弃已读取的数据
|
||||
_, _ = c.Discard(totalLen)
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user