package transport
import (
"encoding/binary"
"errors"
"io"
"math"
"sync"
)
const (
sizeLen = 5 //设置消息多少字节大小,1<<4*8-1长度,最后一个字节用来做消息分割的,防止恶意链接
)
var (
ErrLength = errors.New("message too large")
ErrHeader = errors.New("message head error")
)
//添加数据头并发送
func SedMsg(w io.Writer, p []byte) error {
msglen := len(p)
if msglen > math.MaxUint32 {
return ErrLength
}
var buf = make([]byte, sizeLen+msglen)
binary.BigEndian.PutUint32(buf, uint32(msglen))
copy(buf[sizeLen:], p)
_, err := w.Write(buf)
return err
}
//从数据流中根据头长度读取完整的消息
func RcvMsg(r io.Reader, lock sync.Locker) ([]byte, error) {
lock.Lock()
defer lock.Unlock()
var header [sizeLen]byte
if _, err := io.ReadFull(r, header[:]); err != nil {
return nil, err
}
if header[sizeLen-1] == 0 {
length := binary.BigEndian.Uint32(header[:])
if length == 0 {
return nil, nil
}
msg := make([]byte, int(length))
if _, err := io.ReadFull(r, msg); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
msg = msg[:0]
return nil, err
}
return msg, nil
}
return nil, ErrHeader
}
Go1.7.3一个收发消息的小接口
最新推荐文章于 2023-12-26 15:53:36 发布