zinx
zinx copied to clipboard
读取链接流,使用Scanner建议
目前的读取数据。似乎无解决粘包问题! 改进建议: 24是我这边协议的包头长度。
func (c *Connection) StartReader() {
dataPacker := NewDataPack()
scanner := bufio.NewScanner(c.Conn)
buf := make([]byte, 24)
scanner.Buffer(buf, bufio.MaxScanTokenSize)
scanner.Split(c.splitPack)
for scanner.Scan() {
c.Conn.SetReadDeadline(time.Now().Add(utils.GlobalObject.KeepAlive))
msg, err := dataPacker.Unpack(scanner.Bytes())
if err != nil {
logger.Error("unpack error ", err)
continue
}
logger.Debugf("Tcp receive msg:%s", msg.GetBody())
var jsonObj dto.Result
json.Unmarshal(msg.GetBody(), &jsonObj)
//得到当前客户端请求的Request数据
req := Request{
conn: c,
msg: msg,
ret: jsonObj,
}
if utils.GlobalObject.WorkerPoolSize > 0 {
//已经启动工作池机制,将消息交给Worker处理
c.MsgHandler.SendMsgToTaskQueue(&req)
} else {
//从绑定好的消息和对应的处理方法中执行对应的Handle方法
go c.MsgHandler.DoMsgHandler(&req)
}
}
}
func (c *Connection) splitPack(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF {
return 0, nil, io.EOF
}
// 4个字节是包头的长度
if len(data) <= 4 {
return 0, nil, nil
}
var bodySize int = (int)(binary.LittleEndian.Uint32(data))
pkgLength := bodySize + 24 //包头长度24
if len(data) < pkgLength {
return 0, nil, nil
}
return pkgLength, data[:pkgLength], nil
}
想法不错,可以提PR哈。 而且为什么说现在解决不了粘包呢,现在也是可以解决的,你这种Scanner的方式也不错。但是包头定义24,和目前客户端那个案例的协议不太符合。你还有改成8的版本的吗。
粘包问题查看最新版本