4 Star 6 Fork 3

王军 / golib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
send.go 3.43 KB
一键复制 编辑 原始数据 按行查看 历史
王军 提交于 2023-08-28 09:17 . 自动匹配
package wall
//发送文件不合并
import (
"bytes"
"encoding/binary"
"errors"
"io/ioutil"
"net"
"time"
"gitee.com/haodreams/golib/logs"
"gitee.com/haodreams/libs/sock"
"gitee.com/haodreams/libs/config"
"github.com/pierrec/lz4"
)
// MaskLz4 .
const (
MaskLz4 = 0x8000
MaskNone = 0x7ff
MaxSize = 32*1024 - 1
)
// Send 发送
type Send struct {
interval int //扫描间隔
limitSpeed int //限速 K byte/s
ackChar byte //确认字符
remoteServer string //远程服务器地址
conn *net.TCPConn // tcp 连接
bytePerMS int //一毫秒最多发送的字节数
compressionLevel int //压缩级别
timeout time.Duration
}
// NewSend .
func NewSend(conf config.Configer) *Send {
s := new(Send)
s.limitSpeed = conf.DefaultInt("send_limit_speed", 0) //不限速
s.interval = conf.DefaultInt("send_scan_interval", 5)
s.remoteServer = conf.String("remote_server")
s.ackChar = byte(conf.DefaultInt("ack_char", 0))
s.timeout = time.Duration(conf.DefaultInt("timeout", 30)) * time.Second
s.compressionLevel = conf.DefaultInt("compression_level", 5)
if s.remoteServer == "" {
logs.Error("服务器地址为空。")
return nil
}
s.bytePerMS = s.limitSpeed * 1024 / 1000 //每毫秒发送的字节数
return s
}
// Reconnect 重新连接
func (m *Send) Reconnect() (err error) {
if m.conn == nil {
logs.Info("Connect to server,", m.remoteServer)
m.conn, err = sock.CreateTcpConnect(m.remoteServer)
if err != nil {
m.conn = nil
return
}
logs.Info("Connect to server success")
}
return
}
// Write .
func (m *Send) Write(data []byte) (num int, err error) {
num = len(data)
i := 0
for ; i < num; i += MaxSize {
pos := i + MaxSize
if pos > num {
pos = num
}
err = m.write(data[i:pos])
if err != nil {
return
}
}
if i < num {
err = m.write(data[i:num])
if err != nil {
return
}
}
return
}
// 发送一个数据包
func (m *Send) write(data []byte) (err error) {
//接收应答帧
mask, data := Lz4Encode(data)
l := uint16(len(data))
l |= mask
head := make([]byte, 2)
binary.BigEndian.PutUint16(head, l)
_, err = m.conn.Write(head)
if err != nil {
return
}
_, err = m.conn.Write(data)
if err != nil {
return
}
//30秒内要对数据包做出应答
err = m.conn.SetReadDeadline(time.Now().Add(m.timeout))
if err != nil {
m.conn.Close()
m.conn = nil
return
}
ack := make([]byte, 1)
_, err = m.conn.Read(ack)
if err != nil {
m.conn.Close()
m.conn = nil
return
}
if ack[0] != m.ackChar {
err = errors.New("ACK ERROR")
}
return
}
// Lz4Encode 最大32k
func Lz4Encode(data []byte, level ...int) (mask uint16, b []byte) {
buf := bytes.NewBuffer(nil)
zw := lz4.NewWriter(buf)
zw.BlockMaxSize = MaxSize
zw.CompressionLevel = 0
if len(level) > 0 {
zw.CompressionLevel = level[0]
}
_, err := zw.Write(data)
if err != nil {
return 0, data
}
err = zw.Close()
if err != nil {
return 0, data
}
if len(data) < buf.Len() {
return 0, data
}
return MaskLz4, buf.Bytes()
}
// Lz4Decode .
func Lz4Decode(data []byte) (b []byte, err error) {
mask := binary.BigEndian.Uint16(data)
if mask&MaskLz4 == MaskLz4 {
return data[2:], nil
}
zr := lz4.NewReader(bytes.NewBuffer(data[2:]))
b, err = ioutil.ReadAll(zr)
return
}
Go
1
https://gitee.com/haodreams/golib.git
git@gitee.com:haodreams/golib.git
haodreams
golib
golib
9c7efcecc68a

搜索帮助

53164aa7 5694891 3bd8fe86 5694891