gf/net/gtcp/gtcp_func.go

132 lines
3.4 KiB
Go
Raw Normal View History

// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
2018-07-18 11:43:30 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
2018-07-18 11:43:30 +08:00
package gtcp
import (
2019-06-04 23:33:46 +08:00
"crypto/rand"
"crypto/tls"
"net"
"time"
2019-07-29 21:01:19 +08:00
"github.com/gogf/gf/os/gfile"
2018-07-18 11:43:30 +08:00
)
const (
2019-06-19 09:06:52 +08:00
gDEFAULT_RETRY_INTERVAL = 100 // (毫秒)默认重试时间间隔
gDEFAULT_READ_BUFFER_SIZE = 128 // (byte)默认数据读取缓冲区大小
2018-07-18 11:43:30 +08:00
)
type Retry struct {
2019-06-19 09:06:52 +08:00
Count int // 重试次数
Interval int // 重试间隔(毫秒)
2018-07-18 11:43:30 +08:00
}
2019-06-04 23:33:46 +08:00
// Deprecated.
2018-07-18 11:43:30 +08:00
// 常见的二进制数据校验方式,生成校验结果
func Checksum(buffer []byte) uint32 {
2019-06-19 09:06:52 +08:00
var checksum uint32
for _, b := range buffer {
checksum += uint32(b)
}
return checksum
2018-07-18 11:43:30 +08:00
}
// 创建原生TCP链接, addr地址格式形如127.0.0.1:80
2019-06-19 09:06:52 +08:00
func NewNetConn(addr string, timeout ...int) (net.Conn, error) {
if len(timeout) > 0 {
return net.DialTimeout("tcp", addr, time.Duration(timeout[0])*time.Millisecond)
} else {
return net.Dial("tcp", addr)
}
2018-07-18 11:43:30 +08:00
}
2019-06-04 23:33:46 +08:00
// 创建支持TLS的原生TCP链接, addr地址格式形如127.0.0.1:80
func NewNetConnTLS(addr string, tlsConfig *tls.Config) (net.Conn, error) {
return tls.Dial("tcp", addr, tlsConfig)
}
// 根据给定的证书和密钥文件创建支持TLS的原生TCP链接, addr地址格式形如127.0.0.1:80
func NewNetConnKeyCrt(addr, crtFile, keyFile string) (net.Conn, error) {
tlsConfig, err := LoadKeyCrt(crtFile, keyFile)
if err != nil {
return nil, err
}
return NewNetConnTLS(addr, tlsConfig)
}
2018-07-18 11:43:30 +08:00
// (面向短链接)发送数据
2019-06-19 09:06:52 +08:00
func Send(addr string, data []byte, retry ...Retry) error {
conn, err := NewConn(addr)
if err != nil {
return err
}
defer conn.Close()
return conn.Send(data, retry...)
2018-07-18 11:43:30 +08:00
}
// (面向短链接)发送数据并等待接收返回数据
2019-06-19 09:06:52 +08:00
func SendRecv(addr string, data []byte, receive int, retry ...Retry) ([]byte, error) {
2019-04-28 23:55:23 +08:00
conn, err := NewConn(addr)
if err != nil {
return nil, err
}
defer conn.Close()
return conn.SendRecv(data, receive, retry...)
2018-07-18 11:43:30 +08:00
}
// (面向短链接)带超时时间的数据发送
2019-06-19 09:06:52 +08:00
func SendWithTimeout(addr string, data []byte, timeout time.Duration, retry ...Retry) error {
conn, err := NewConn(addr)
if err != nil {
return err
}
defer conn.Close()
return conn.SendWithTimeout(data, timeout, retry...)
2018-07-18 11:43:30 +08:00
}
// (面向短链接)发送数据并等待接收返回数据(带返回超时等待时间)
2019-06-19 09:06:52 +08:00
func SendRecvWithTimeout(addr string, data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) {
conn, err := NewConn(addr)
if err != nil {
return nil, err
}
defer conn.Close()
return conn.SendRecvWithTimeout(data, receive, timeout, retry...)
2018-07-18 11:43:30 +08:00
}
2018-08-06 21:19:48 +08:00
// 判断是否是超时错误
func isTimeout(err error) bool {
2019-06-19 09:06:52 +08:00
if err == nil {
return false
}
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
return true
}
return false
2019-06-04 23:33:46 +08:00
}
// 根据证书和密钥生成TLS对象
func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) {
crtPath, err := gfile.Search(crtFile)
if err != nil {
return nil, err
}
keyPath, err := gfile.Search(keyFile)
if err != nil {
return nil, err
}
crt, err := tls.LoadX509KeyPair(crtPath, keyPath)
if err != nil {
return nil, err
}
2019-06-19 09:06:52 +08:00
tlsConfig := &tls.Config{}
2019-06-04 23:33:46 +08:00
tlsConfig.Certificates = []tls.Certificate{crt}
2019-06-19 09:06:52 +08:00
tlsConfig.Time = time.Now
tlsConfig.Rand = rand.Reader
2019-06-04 23:33:46 +08:00
return tlsConfig, nil
2019-06-19 09:06:52 +08:00
}