2025-02-24 17:21:47 +08:00
|
|
|
package utils
|
|
|
|
|
|
2025-02-25 00:46:16 +08:00
|
|
|
import (
|
2025-02-25 14:48:50 +08:00
|
|
|
"context"
|
2025-02-25 00:46:16 +08:00
|
|
|
"io"
|
|
|
|
|
"log/slog"
|
2025-02-25 14:48:50 +08:00
|
|
|
"net"
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2025-02-25 00:46:16 +08:00
|
|
|
)
|
2025-02-24 17:21:47 +08:00
|
|
|
|
|
|
|
|
func ReadByte(reader io.Reader) (byte, error) {
|
|
|
|
|
buffer, err := ReadBuffer(reader, 1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buffer[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ReadBuffer(reader io.Reader, size int) ([]byte, error) {
|
|
|
|
|
buffer := make([]byte, size)
|
|
|
|
|
_, err := io.ReadFull(reader, buffer)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buffer, nil
|
|
|
|
|
}
|
2025-02-25 00:46:16 +08:00
|
|
|
|
2025-02-25 11:39:54 +08:00
|
|
|
// Close 关闭对象,传入值绝对不能为 nil
|
|
|
|
|
func Close[T io.Closer](v T) {
|
|
|
|
|
err := v.Close()
|
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Warn("对象关闭失败", "err", err)
|
2025-02-25 00:46:16 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-02-25 14:48:50 +08:00
|
|
|
|
|
|
|
|
func ConnChan(ctx context.Context, ls net.Listener) chan net.Conn {
|
|
|
|
|
connCh := make(chan net.Conn)
|
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
conn, err := ls.Accept()
|
|
|
|
|
if err != nil {
|
|
|
|
|
slog.Error("接受连接失败", err)
|
|
|
|
|
// 临时错误重试连接
|
|
|
|
|
var ne net.Error
|
|
|
|
|
if errors.As(err, &ne) && ne.Temporary() {
|
|
|
|
|
slog.Debug("临时错误重试")
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// ctx 取消后退出
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
Close(conn)
|
|
|
|
|
return
|
|
|
|
|
case connCh <- conn:
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
return connCh
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func WaitChan(ctx context.Context, wg *sync.WaitGroup) chan struct{} {
|
|
|
|
|
ch := make(chan struct{})
|
|
|
|
|
go func() {
|
|
|
|
|
wg.Wait()
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
case ch <- struct{}{}:
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
return ch
|
|
|
|
|
}
|