mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
comment update for package gtcp/gipv4/gipv6
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := context.WithValue(context.Background(), "key", "value")
|
||||
fmt.Printf("%v", c)
|
||||
c1 := context.WithValue(context.Background(), "key1", "value1")
|
||||
c2 := context.WithValue(c1, "key2", "value2")
|
||||
fmt.Printf("%v", c2.Value("key2"))
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ type ExpireFunc func(interface{})
|
||||
// New returns a new object pool.
|
||||
// To ensure execution efficiency, the expiration time cannot be modified once it is set.
|
||||
//
|
||||
// Expiration logistics:
|
||||
// Expiration logic:
|
||||
// expire = 0 : not expired;
|
||||
// expire < 0 : immediate expired after use;
|
||||
// expire > 0 : timeout expired;
|
||||
|
||||
@ -12,19 +12,18 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
)
|
||||
|
||||
// 判断所给地址是否是一个IPv4地址
|
||||
// Validate checks whether given <ip> a valid IPv4 address.
|
||||
func Validate(ip string) bool {
|
||||
return gregex.IsMatchString(`^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$`, ip)
|
||||
}
|
||||
|
||||
// Get the IPv4 address corresponding to a given Internet host name.
|
||||
// GetHostByName returns the IPv4 address corresponding to a given Internet host name.
|
||||
func GetHostByName(hostname string) (string, error) {
|
||||
ips, err := net.LookupIP(hostname)
|
||||
if ips != nil {
|
||||
@ -38,22 +37,22 @@ func GetHostByName(hostname string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Get a list of IPv4 addresses corresponding to a given Internet host name.
|
||||
// GetHostsByName returns a list of IPv4 addresses corresponding to a given Internet host name.
|
||||
func GetHostsByName(hostname string) ([]string, error) {
|
||||
ips, err := net.LookupIP(hostname)
|
||||
if ips != nil {
|
||||
var ipStrs []string
|
||||
var ipStrings []string
|
||||
for _, v := range ips {
|
||||
if v.To4() != nil {
|
||||
ipStrs = append(ipStrs, v.String())
|
||||
ipStrings = append(ipStrings, v.String())
|
||||
}
|
||||
}
|
||||
return ipStrs, nil
|
||||
return ipStrings, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the Internet host name corresponding to a given IP address.
|
||||
// GetNameByAddr returns the Internet host name corresponding to a given IP address.
|
||||
func GetNameByAddr(ipAddress string) (string, error) {
|
||||
names, err := net.LookupAddr(ipAddress)
|
||||
if names != nil {
|
||||
@ -62,7 +61,7 @@ func GetNameByAddr(ipAddress string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// IP字符串转为整形.
|
||||
// Ip2long converts ip address to an uint32 integer.
|
||||
func Ip2long(ipAddress string) uint32 {
|
||||
ip := net.ParseIP(ipAddress)
|
||||
if ip == nil {
|
||||
@ -71,43 +70,35 @@ func Ip2long(ipAddress string) uint32 {
|
||||
return binary.BigEndian.Uint32(ip.To4())
|
||||
}
|
||||
|
||||
// ip整形转为字符串
|
||||
// Long2ip converts an uint32 integer ip address to its string type address.
|
||||
func Long2ip(properAddress uint32) string {
|
||||
ipByte := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(ipByte, properAddress)
|
||||
return net.IP(ipByte).String()
|
||||
}
|
||||
|
||||
// 获得ip的网段,例如:192.168.2.102 -> 192.168.2
|
||||
// GetSegment returns the segment of given ip address.
|
||||
// Eg: 192.168.2.102 -> 192.168.2
|
||||
func GetSegment(ip string) string {
|
||||
r := `^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$`
|
||||
reg, err := regexp.Compile(r)
|
||||
if err != nil {
|
||||
match, err := gregex.MatchString(`^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$`, ip)
|
||||
if err != nil || len(match) < 4 {
|
||||
return ""
|
||||
}
|
||||
ips := reg.FindStringSubmatch(ip)
|
||||
if ips == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s.%s.%s", ips[1], ips[2], ips[3])
|
||||
return fmt.Sprintf("%s.%s.%s", match[1], match[2], match[3])
|
||||
}
|
||||
|
||||
// 解析地址,形如:192.168.1.1:80 -> 192.168.1.1, 80
|
||||
func ParseAddress(addr string) (string, int) {
|
||||
r := `^(.+):(\d+)$`
|
||||
reg, err := regexp.Compile(r)
|
||||
if err != nil {
|
||||
return "", 0
|
||||
}
|
||||
result := reg.FindStringSubmatch(addr)
|
||||
if result != nil {
|
||||
i, _ := strconv.Atoi(result[2])
|
||||
return result[1], i
|
||||
// ParseAddress parses <address> to its ip and port.
|
||||
// Eg: 192.168.1.1:80 -> 192.168.1.1, 80
|
||||
func ParseAddress(address string) (string, int) {
|
||||
match, err := gregex.MatchString(`^(.+):(\d+)$`, address)
|
||||
if err == nil {
|
||||
i, _ := strconv.Atoi(match[2])
|
||||
return match[1], i
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
||||
// 获取本地局域网ip列表
|
||||
// IntranetIP returns the intranet ip list of current machine.
|
||||
func IntranetIP() (ips []string, err error) {
|
||||
ips = make([]string, 0)
|
||||
ifaces, e := net.Interfaces()
|
||||
@ -116,24 +107,22 @@ func IntranetIP() (ips []string, err error) {
|
||||
}
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue // interface down
|
||||
// interface down
|
||||
continue
|
||||
}
|
||||
|
||||
if iface.Flags&net.FlagLoopback != 0 {
|
||||
continue // loopback interface
|
||||
// loopback interface
|
||||
continue
|
||||
}
|
||||
|
||||
// ignore warden bridge
|
||||
if strings.HasPrefix(iface.Name, "w-") {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, e := iface.Addrs()
|
||||
addresses, e := iface.Addrs()
|
||||
if e != nil {
|
||||
return ips, e
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
for _, addr := range addresses {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
@ -145,12 +134,11 @@ func IntranetIP() (ips []string, err error) {
|
||||
if ip == nil || ip.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
continue // not an ipv4 address
|
||||
// not an ipv4 address
|
||||
continue
|
||||
}
|
||||
|
||||
ipStr := ip.String()
|
||||
if IsIntranet(ipStr) {
|
||||
ips = append(ips, ipStr)
|
||||
@ -160,31 +148,32 @@ func IntranetIP() (ips []string, err error) {
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
// 判断所给ip是否为局域网ip
|
||||
// A类 10.0.0.0--10.255.255.255
|
||||
// B类 172.16.0.0--172.31.255.255
|
||||
// C类 192.168.0.0--192.168.255.255
|
||||
func IsIntranet(ipStr string) bool {
|
||||
// ip协议保留的局域网ip
|
||||
if strings.HasPrefix(ipStr, "10.") || strings.HasPrefix(ipStr, "192.168.") {
|
||||
// IsIntranet checks and returns whether given ip an intranet ip.
|
||||
// A: 10.0.0.0--10.255.255.255
|
||||
// B: 172.16.0.0--172.31.255.255
|
||||
// C: 192.168.0.0--192.168.255.255
|
||||
func IsIntranet(ip string) bool {
|
||||
array := strings.Split(ip, ".")
|
||||
if len(array) != 4 {
|
||||
return false
|
||||
}
|
||||
// A
|
||||
if array[0] == "10" || (array[0] == "192" && array[1] == "168") {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(ipStr, "172.") {
|
||||
// 172.16.0.0 - 172.31.255.255
|
||||
arr := strings.Split(ipStr, ".")
|
||||
if len(arr) != 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
second, err := strconv.ParseInt(arr[1], 10, 64)
|
||||
// C
|
||||
if array[0] == "192" && array[1] == "168" {
|
||||
return true
|
||||
}
|
||||
// B
|
||||
if array[0] == "172" {
|
||||
second, err := strconv.ParseInt(array[1], 10, 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if second >= 16 && second <= 31 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ package gipv6
|
||||
|
||||
import "github.com/gogf/gf/text/gregex"
|
||||
|
||||
// 判断所给地址是否是一个IPv6地址
|
||||
// Validate checks whether given <ip> a valid IPv6 address.
|
||||
func Validate(ip string) bool {
|
||||
return gregex.IsMatchString(`^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$`, ip)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
// Package gsmtp provides a SMTP client to access remote mail server.
|
||||
//
|
||||
// eg:
|
||||
// Eg:
|
||||
// s := smtp.New("smtp.exmail.qq.com:25", "notify@a.com", "password")
|
||||
// glog.Println(s.SendMail("notify@a.com", "ulric@b.com;rain@c.com", "subject", "body, <font color=red>red</font>"))
|
||||
package gsmtp
|
||||
|
||||
@ -31,7 +31,7 @@ const (
|
||||
)
|
||||
|
||||
// NewConn creates and returns a new connection with given address.
|
||||
func NewConn(addr string, timeout ...int) (*Conn, error) {
|
||||
func NewConn(addr string, timeout ...time.Duration) (*Conn, error) {
|
||||
if conn, err := NewNetConn(addr, timeout...); err == nil {
|
||||
return NewConnByNetConn(conn), nil
|
||||
} else {
|
||||
@ -95,7 +95,7 @@ func (c *Conn) Send(data []byte, retry ...Retry) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Recv receives data from remote address.
|
||||
// Recv receives data from the connection.
|
||||
//
|
||||
// Note that,
|
||||
// 1. If length = 0, it means it receives the data from current buffer and returns immediately.
|
||||
@ -177,8 +177,8 @@ func (c *Conn) Recv(length int, retry ...Retry) ([]byte, error) {
|
||||
return buffer[:index], err
|
||||
}
|
||||
|
||||
// RecvLine reads data from connection until reads char '\n'.
|
||||
// Note that the returned result does not contain char '\n'.
|
||||
// RecvLine reads data from the connection until reads char '\n'.
|
||||
// Note that the returned result does not contain the last char '\n'.
|
||||
func (c *Conn) RecvLine(retry ...Retry) ([]byte, error) {
|
||||
var err error
|
||||
var buffer []byte
|
||||
@ -201,7 +201,7 @@ func (c *Conn) RecvLine(retry ...Retry) ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// RecvWithTimeout reads data from connection with timeout.
|
||||
// RecvWithTimeout reads data from the connection with timeout.
|
||||
func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry) (data []byte, err error) {
|
||||
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return nil, err
|
||||
@ -211,7 +211,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry
|
||||
return
|
||||
}
|
||||
|
||||
// SendWithTimeout writes data to connection with timeout.
|
||||
// SendWithTimeout writes data to the connection with timeout.
|
||||
func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retry) (err error) {
|
||||
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return err
|
||||
@ -221,19 +221,19 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr
|
||||
return
|
||||
}
|
||||
|
||||
// SendRecv writes data to connection and blocks reading response.
|
||||
func (c *Conn) SendRecv(data []byte, receive int, retry ...Retry) ([]byte, error) {
|
||||
// SendRecv writes data to the connection and blocks reading response.
|
||||
func (c *Conn) SendRecv(data []byte, length int, retry ...Retry) ([]byte, error) {
|
||||
if err := c.Send(data, retry...); err == nil {
|
||||
return c.Recv(receive, retry...)
|
||||
return c.Recv(length, retry...)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// SendRecvWithTimeout writes data to connection and reads response with timeout.
|
||||
func (c *Conn) SendRecvWithTimeout(data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) {
|
||||
// SendRecvWithTimeout writes data to the connection and reads response with timeout.
|
||||
func (c *Conn) SendRecvWithTimeout(data []byte, length int, timeout time.Duration, retry ...Retry) ([]byte, error) {
|
||||
if err := c.Send(data, retry...); err == nil {
|
||||
return c.RecvWithTimeout(receive, timeout, retry...)
|
||||
return c.RecvWithTimeout(length, timeout, retry...)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ const (
|
||||
|
||||
// Package option for simple protocol.
|
||||
type PkgOption struct {
|
||||
HeaderSize int // It's 2 bytes in default, max is 4 bytes.
|
||||
MaxDataSize int // (Byte)data field size, it's 2 bytes in default, which means 65535 bytes.
|
||||
HeaderSize int // It's 2 bytes in default, 4 bytes max.
|
||||
MaxDataSize int // (Byte) Data field size, it's 2 bytes in default, which means 65535 bytes.
|
||||
Retry Retry // Retry policy.
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ func (c *Conn) SendRecvPkgWithTimeout(data []byte, timeout time.Duration, option
|
||||
}
|
||||
}
|
||||
|
||||
// Recv receives data from connection using simple package protocol.
|
||||
// RecvPkg receives data from connection using simple package protocol.
|
||||
func (c *Conn) RecvPkg(option ...PkgOption) (result []byte, err error) {
|
||||
var temp []byte
|
||||
var length int
|
||||
|
||||
@ -16,41 +16,53 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
gDEFAULT_RETRY_INTERVAL = 100 // (毫秒)默认重试时间间隔
|
||||
gDEFAULT_READ_BUFFER_SIZE = 128 // (byte)默认数据读取缓冲区大小
|
||||
gDEFAULT_CONN_TIMEOUT = 30 * time.Second // Default connection timeout.
|
||||
gDEFAULT_RETRY_INTERVAL = 100 * time.Millisecond // Default retry interval.
|
||||
gDEFAULT_READ_BUFFER_SIZE = 128 // (Byte) Buffer size for reading.
|
||||
)
|
||||
|
||||
type Retry struct {
|
||||
Count int // 重试次数
|
||||
Interval int // 重试间隔(毫秒)
|
||||
Count int // Retry count.
|
||||
Interval time.Duration // Retry interval.
|
||||
}
|
||||
|
||||
// 创建原生TCP链接, addr地址格式形如:127.0.0.1:80
|
||||
func NewNetConn(addr string, timeout ...int) (net.Conn, error) {
|
||||
// NewNetConn creates and returns a net.Conn with given address like "127.0.0.1:80".
|
||||
// The optional parameter <timeout> specifies the timeout for dialing connection.
|
||||
func NewNetConn(addr string, timeout ...time.Duration) (net.Conn, error) {
|
||||
d := gDEFAULT_CONN_TIMEOUT
|
||||
if len(timeout) > 0 {
|
||||
return net.DialTimeout("tcp", addr, time.Duration(timeout[0])*time.Millisecond)
|
||||
} else {
|
||||
return net.Dial("tcp", addr)
|
||||
d = timeout[0]
|
||||
}
|
||||
return net.DialTimeout("tcp", addr, d)
|
||||
}
|
||||
|
||||
// 创建支持TLS的原生TCP链接, addr地址格式形如:127.0.0.1:80
|
||||
func NewNetConnTLS(addr string, tlsConfig *tls.Config) (net.Conn, error) {
|
||||
return tls.Dial("tcp", addr, tlsConfig)
|
||||
// NewNetConnTLS creates and returns a TLS net.Conn with given address like "127.0.0.1:80".
|
||||
// The optional parameter <timeout> specifies the timeout for dialing connection.
|
||||
func NewNetConnTLS(addr string, tlsConfig *tls.Config, timeout ...time.Duration) (net.Conn, error) {
|
||||
dialer := &net.Dialer{
|
||||
Timeout: gDEFAULT_CONN_TIMEOUT,
|
||||
}
|
||||
if len(timeout) > 0 {
|
||||
dialer.Timeout = timeout[0]
|
||||
}
|
||||
return tls.DialWithDialer(dialer, "tcp", addr, tlsConfig)
|
||||
}
|
||||
|
||||
// 根据给定的证书和密钥文件创建支持TLS的原生TCP链接, addr地址格式形如:127.0.0.1:80
|
||||
func NewNetConnKeyCrt(addr, crtFile, keyFile string) (net.Conn, error) {
|
||||
// NewNetConnKeyCrt creates and returns a TLS net.Conn with given TLS certificate and key files
|
||||
// and address like "127.0.0.1:80". The optional parameter <timeout> specifies the timeout for
|
||||
// dialing connection.
|
||||
func NewNetConnKeyCrt(addr, crtFile, keyFile string, timeout ...time.Duration) (net.Conn, error) {
|
||||
tlsConfig, err := LoadKeyCrt(crtFile, keyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewNetConnTLS(addr, tlsConfig)
|
||||
return NewNetConnTLS(addr, tlsConfig, timeout...)
|
||||
}
|
||||
|
||||
// (面向短链接)发送数据
|
||||
func Send(addr string, data []byte, retry ...Retry) error {
|
||||
conn, err := NewConn(addr)
|
||||
// Send creates connection to <address>, writes <data> to the connection and then closes the connection.
|
||||
// The optional parameter <retry> specifies the retry policy when fails in writing data.
|
||||
func Send(address string, data []byte, retry ...Retry) error {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -58,19 +70,25 @@ func Send(addr string, data []byte, retry ...Retry) error {
|
||||
return conn.Send(data, retry...)
|
||||
}
|
||||
|
||||
// (面向短链接)发送数据并等待接收返回数据
|
||||
func SendRecv(addr string, data []byte, receive int, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(addr)
|
||||
// SendRecv creates connection to <address>, writes <data> to the connection, receives response
|
||||
// and then closes the connection.
|
||||
//
|
||||
// The parameter <length> specifies the bytes count waiting to receive. It receives all buffer content
|
||||
// and returns if <length> is -1.
|
||||
//
|
||||
// The optional parameter <retry> specifies the retry policy when fails in writing data.
|
||||
func SendRecv(address string, data []byte, length int, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
return conn.SendRecv(data, receive, retry...)
|
||||
return conn.SendRecv(data, length, retry...)
|
||||
}
|
||||
|
||||
// (面向短链接)带超时时间的数据发送
|
||||
func SendWithTimeout(addr string, data []byte, timeout time.Duration, retry ...Retry) error {
|
||||
conn, err := NewConn(addr)
|
||||
// SendWithTimeout does Send logic with writing timeout limitation.
|
||||
func SendWithTimeout(address string, data []byte, timeout time.Duration, retry ...Retry) error {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,9 +96,9 @@ func SendWithTimeout(addr string, data []byte, timeout time.Duration, retry ...R
|
||||
return conn.SendWithTimeout(data, timeout, retry...)
|
||||
}
|
||||
|
||||
// (面向短链接)发送数据并等待接收返回数据(带返回超时等待时间)
|
||||
func SendRecvWithTimeout(addr string, data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(addr)
|
||||
// SendRecvWithTimeout does SendRecv logic with reading timeout limitation.
|
||||
func SendRecvWithTimeout(address string, data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -88,7 +106,7 @@ func SendRecvWithTimeout(addr string, data []byte, receive int, timeout time.Dur
|
||||
return conn.SendRecvWithTimeout(data, receive, timeout, retry...)
|
||||
}
|
||||
|
||||
// 判断是否是超时错误
|
||||
// isTimeout checks whether given <err> is a timeout error.
|
||||
func isTimeout(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
@ -99,7 +117,7 @@ func isTimeout(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// 根据证书和密钥生成TLS对象
|
||||
// LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files.
|
||||
func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) {
|
||||
crtPath, err := gfile.Search(crtFile)
|
||||
if err != nil {
|
||||
|
||||
@ -8,9 +8,10 @@ package gtcp
|
||||
|
||||
import "time"
|
||||
|
||||
// 简单协议: (面向短链接)发送消息包
|
||||
func SendPkg(addr string, data []byte, option ...PkgOption) error {
|
||||
conn, err := NewConn(addr)
|
||||
// SendPkg sends a package containing <data> to <address> and closes the connection.
|
||||
// The optional parameter <option> specifies the package options for sending.
|
||||
func SendPkg(address string, data []byte, option ...PkgOption) error {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -18,9 +19,10 @@ func SendPkg(addr string, data []byte, option ...PkgOption) error {
|
||||
return conn.SendPkg(data, option...)
|
||||
}
|
||||
|
||||
// 简单协议: (面向短链接)发送数据并等待接收返回数据
|
||||
func SendRecvPkg(addr string, data []byte, option ...PkgOption) ([]byte, error) {
|
||||
conn, err := NewConn(addr)
|
||||
// SendRecvPkg sends a package containing <data> to <address>, receives the response
|
||||
// and closes the connection. The optional parameter <option> specifies the package options for sending.
|
||||
func SendRecvPkg(address string, data []byte, option ...PkgOption) ([]byte, error) {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -28,9 +30,10 @@ func SendRecvPkg(addr string, data []byte, option ...PkgOption) ([]byte, error)
|
||||
return conn.SendRecvPkg(data, option...)
|
||||
}
|
||||
|
||||
// 简单协议: (面向短链接)带超时时间的数据发送
|
||||
func SendPkgWithTimeout(addr string, data []byte, timeout time.Duration, option ...PkgOption) error {
|
||||
conn, err := NewConn(addr)
|
||||
// SendPkgWithTimeout sends a package containing <data> to <address> with timeout limitation
|
||||
// and closes the connection. The optional parameter <option> specifies the package options for sending.
|
||||
func SendPkgWithTimeout(address string, data []byte, timeout time.Duration, option ...PkgOption) error {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -38,9 +41,10 @@ func SendPkgWithTimeout(addr string, data []byte, timeout time.Duration, option
|
||||
return conn.SendPkgWithTimeout(data, timeout, option...)
|
||||
}
|
||||
|
||||
// 简单协议: (面向短链接)发送数据并等待接收返回数据(带返回超时等待时间)
|
||||
func SendRecvPkgWithTimeout(addr string, data []byte, timeout time.Duration, option ...PkgOption) ([]byte, error) {
|
||||
conn, err := NewConn(addr)
|
||||
// SendRecvPkgWithTimeout sends a package containing <data> to <address>, receives the response with timeout limitation
|
||||
// and closes the connection. The optional parameter <option> specifies the package options for sending.
|
||||
func SendRecvPkgWithTimeout(address string, data []byte, timeout time.Duration, option ...PkgOption) ([]byte, error) {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -13,31 +13,32 @@ import (
|
||||
"github.com/gogf/gf/container/gpool"
|
||||
)
|
||||
|
||||
// 链接池链接对象
|
||||
// PoolConn is a connection with pool feature for TCP.
|
||||
// Note that it is NOT a pool or connection manager,
|
||||
// it is just a TCP connection object.
|
||||
type PoolConn struct {
|
||||
*Conn // 继承底层链接接口对象
|
||||
pool *gpool.Pool // 对应的链接池对象
|
||||
status int // 当前对象的状态,主要用于失败重连判断
|
||||
*Conn // Underlying connection object.
|
||||
pool *gpool.Pool // Connection pool, which is not a really connection pool, but a connection reusable pool.
|
||||
status int // Status of current connection, which is used to mark this connection usable or not.
|
||||
}
|
||||
|
||||
const (
|
||||
gDEFAULT_POOL_EXPIRE = 60000 // (毫秒)默认链接对象过期时间
|
||||
gCONN_STATUS_UNKNOWN = 0 // 未知,表示未经过连通性操作;
|
||||
gCONN_STATUS_ACTIVE = 1 // 正常,表示已经经过连通性操作
|
||||
gCONN_STATUS_ERROR = 2 // 错误,表示该接口操作产生了错误,不应当被循环使用了
|
||||
|
||||
gDEFAULT_POOL_EXPIRE = 30000 // (Millisecond) Default TTL for connection in the pool.
|
||||
gCONN_STATUS_UNKNOWN = 0 // Means it is unknown it's connective or not.
|
||||
gCONN_STATUS_ACTIVE = 1 // Means it is now connective.
|
||||
gCONN_STATUS_ERROR = 2 // Means it should be closed and removed from pool.
|
||||
)
|
||||
|
||||
var (
|
||||
// 连接池对象map,键名为地址端口,键值为对应的连接池对象
|
||||
pools = gmap.NewStrAnyMap(true)
|
||||
// addressPoolMap is a mapping for address to its pool object.
|
||||
addressPoolMap = gmap.NewStrAnyMap(true)
|
||||
)
|
||||
|
||||
// 创建TCP链接池对象
|
||||
func NewPoolConn(addr string, timeout ...int) (*PoolConn, error) {
|
||||
// NewPoolConn creates and returns a connection with pool feature.
|
||||
func NewPoolConn(addr string, timeout ...time.Duration) (*PoolConn, error) {
|
||||
var pool *gpool.Pool
|
||||
if v := pools.Get(addr); v == nil {
|
||||
pools.LockFunc(func(m map[string]interface{}) {
|
||||
if v := addressPoolMap.Get(addr); v == nil {
|
||||
addressPoolMap.LockFunc(func(m map[string]interface{}) {
|
||||
if v, ok := m[addr]; ok {
|
||||
pool = v.(*gpool.Pool)
|
||||
} else {
|
||||
@ -62,7 +63,8 @@ func NewPoolConn(addr string, timeout ...int) (*PoolConn, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// (方法覆盖)覆盖底层接口对象的Close方法
|
||||
// Close puts back the connection to the pool if it's active,
|
||||
// or closes the connection if it's not active.
|
||||
func (c *PoolConn) Close() error {
|
||||
if c.pool != nil && c.status == gCONN_STATUS_ACTIVE {
|
||||
c.status = gCONN_STATUS_UNKNOWN
|
||||
@ -73,13 +75,14 @@ func (c *PoolConn) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// (方法覆盖)发送数据
|
||||
// Send writes data to the connection. It retrieves a new connection from its pool if it fails
|
||||
// writing data.
|
||||
func (c *PoolConn) Send(data []byte, retry ...Retry) error {
|
||||
var err error
|
||||
if err = c.Conn.Send(data, retry...); err != nil && c.status == gCONN_STATUS_UNKNOWN {
|
||||
if v, e := c.pool.NewFunc(); e == nil {
|
||||
if v, e := c.pool.Get(); e == nil {
|
||||
c.Conn = v.(*PoolConn).Conn
|
||||
err = c.Conn.Send(data, retry...)
|
||||
err = c.Send(data, retry...)
|
||||
} else {
|
||||
err = e
|
||||
}
|
||||
@ -92,7 +95,7 @@ func (c *PoolConn) Send(data []byte, retry ...Retry) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// (方法覆盖)接收数据
|
||||
// Recv receives data from the connection.
|
||||
func (c *PoolConn) Recv(length int, retry ...Retry) ([]byte, error) {
|
||||
data, err := c.Conn.Recv(length, retry...)
|
||||
if err != nil {
|
||||
@ -103,7 +106,8 @@ func (c *PoolConn) Recv(length int, retry ...Retry) ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// (方法覆盖)按行读取数据,阻塞读取,直到完成一行读取位置(末尾以'\n'结尾,返回数据不包含换行符)
|
||||
// RecvLine reads data from the connection until reads char '\n'.
|
||||
// Note that the returned result does not contain the last char '\n'.
|
||||
func (c *PoolConn) RecvLine(retry ...Retry) ([]byte, error) {
|
||||
data, err := c.Conn.RecvLine(retry...)
|
||||
if err != nil {
|
||||
@ -114,7 +118,7 @@ func (c *PoolConn) RecvLine(retry ...Retry) ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// (方法覆盖)带超时时间的数据获取
|
||||
// RecvWithTimeout reads data from the connection with timeout.
|
||||
func (c *PoolConn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry) (data []byte, err error) {
|
||||
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return nil, err
|
||||
@ -124,7 +128,7 @@ func (c *PoolConn) RecvWithTimeout(length int, timeout time.Duration, retry ...R
|
||||
return
|
||||
}
|
||||
|
||||
// (方法覆盖)带超时时间的数据发送
|
||||
// SendWithTimeout writes data to the connection with timeout.
|
||||
func (c *PoolConn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retry) (err error) {
|
||||
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return err
|
||||
@ -134,7 +138,7 @@ func (c *PoolConn) SendWithTimeout(data []byte, timeout time.Duration, retry ...
|
||||
return
|
||||
}
|
||||
|
||||
// (方法覆盖)发送数据并等待接收返回数据
|
||||
// SendRecv writes data to the connection and blocks reading response.
|
||||
func (c *PoolConn) SendRecv(data []byte, receive int, retry ...Retry) ([]byte, error) {
|
||||
if err := c.Send(data, retry...); err == nil {
|
||||
return c.Recv(receive, retry...)
|
||||
@ -143,7 +147,7 @@ func (c *PoolConn) SendRecv(data []byte, receive int, retry ...Retry) ([]byte, e
|
||||
}
|
||||
}
|
||||
|
||||
// (方法覆盖)发送数据并等待接收返回数据(带返回超时等待时间)
|
||||
// SendRecvWithTimeout writes data to the connection and reads response with timeout.
|
||||
func (c *PoolConn) SendRecvWithTimeout(data []byte, receive int, timeout time.Duration, retry ...Retry) ([]byte, error) {
|
||||
if err := c.Send(data, retry...); err == nil {
|
||||
return c.RecvWithTimeout(receive, timeout, retry...)
|
||||
|
||||
@ -10,7 +10,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 简单协议: (方法覆盖)发送数据
|
||||
// SendPkg sends a package containing <data> to the connection.
|
||||
// The optional parameter <option> specifies the package options for sending.
|
||||
func (c *PoolConn) SendPkg(data []byte, option ...PkgOption) (err error) {
|
||||
if err = c.Conn.SendPkg(data, option...); err != nil && c.status == gCONN_STATUS_UNKNOWN {
|
||||
if v, e := c.pool.NewFunc(); e == nil {
|
||||
@ -28,7 +29,8 @@ func (c *PoolConn) SendPkg(data []byte, option ...PkgOption) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// 简单协议: (方法覆盖)接收数据
|
||||
// RecvPkg receives package from connection using simple package protocol.
|
||||
// The optional parameter <option> specifies the package options for receiving.
|
||||
func (c *PoolConn) RecvPkg(option ...PkgOption) ([]byte, error) {
|
||||
data, err := c.Conn.RecvPkg(option...)
|
||||
if err != nil {
|
||||
@ -39,7 +41,7 @@ func (c *PoolConn) RecvPkg(option ...PkgOption) ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// 简单协议: (方法覆盖)带超时时间的数据获取
|
||||
// RecvPkgWithTimeout reads data from connection with timeout using simple package protocol.
|
||||
func (c *PoolConn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption) (data []byte, err error) {
|
||||
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return nil, err
|
||||
@ -49,7 +51,7 @@ func (c *PoolConn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption
|
||||
return
|
||||
}
|
||||
|
||||
// 简单协议: (方法覆盖)带超时时间的数据发送
|
||||
// SendPkgWithTimeout writes data to connection with timeout using simple package protocol.
|
||||
func (c *PoolConn) SendPkgWithTimeout(data []byte, timeout time.Duration, option ...PkgOption) (err error) {
|
||||
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
|
||||
return err
|
||||
@ -59,7 +61,7 @@ func (c *PoolConn) SendPkgWithTimeout(data []byte, timeout time.Duration, option
|
||||
return
|
||||
}
|
||||
|
||||
// 简单协议: (方法覆盖)发送数据并等待接收返回数据
|
||||
// SendRecvPkg writes data to connection and blocks reading response using simple package protocol.
|
||||
func (c *PoolConn) SendRecvPkg(data []byte, option ...PkgOption) ([]byte, error) {
|
||||
if err := c.SendPkg(data, option...); err == nil {
|
||||
return c.RecvPkg(option...)
|
||||
@ -68,7 +70,7 @@ func (c *PoolConn) SendRecvPkg(data []byte, option ...PkgOption) ([]byte, error)
|
||||
}
|
||||
}
|
||||
|
||||
// 简单协议: (方法覆盖)发送数据并等待接收返回数据(带返回超时等待时间)
|
||||
// RecvPkgWithTimeout reads data from connection with timeout using simple package protocol.
|
||||
func (c *PoolConn) SendRecvPkgWithTimeout(data []byte, timeout time.Duration, option ...PkgOption) ([]byte, error) {
|
||||
if err := c.SendPkg(data, option...); err == nil {
|
||||
return c.RecvPkgWithTimeout(timeout, option...)
|
||||
|
||||
@ -17,6 +17,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Default TCP server name.
|
||||
gDEFAULT_SERVER = "default"
|
||||
)
|
||||
|
||||
|
||||
@ -31,10 +31,10 @@ func NewNetConn(remoteAddress string, localAddress ...string) (*net.UDPConn, err
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Send writes data to <addr> using UDP connection and then closes the connection.
|
||||
// Send writes data to <address> using UDP connection and then closes the connection.
|
||||
// Note that it is used for short connection usage.
|
||||
func Send(addr string, data []byte, retry ...Retry) error {
|
||||
conn, err := NewConn(addr)
|
||||
func Send(address string, data []byte, retry ...Retry) error {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -42,10 +42,10 @@ func Send(addr string, data []byte, retry ...Retry) error {
|
||||
return conn.Send(data, retry...)
|
||||
}
|
||||
|
||||
// SendRecv writes data to <addr> using UDP connection, reads response and then closes the connection.
|
||||
// SendRecv writes data to <address> using UDP connection, reads response and then closes the connection.
|
||||
// Note that it is used for short connection usage.
|
||||
func SendRecv(addr string, data []byte, receive int, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(addr)
|
||||
func SendRecv(address string, data []byte, receive int, retry ...Retry) ([]byte, error) {
|
||||
conn, err := NewConn(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -19,10 +19,10 @@ const (
|
||||
gDEFAULT_SERVER = "default"
|
||||
)
|
||||
|
||||
// UDP server.
|
||||
// Server is the UDP server.
|
||||
type Server struct {
|
||||
conn *Conn // UDP server connection object.
|
||||
address string // Listening address.
|
||||
address string // UDP server listening address.
|
||||
handler func(*Conn) // Handler for UDP connection.
|
||||
}
|
||||
|
||||
|
||||
@ -10,11 +10,11 @@ package gmode
|
||||
import "github.com/gogf/gf/os/gfile"
|
||||
|
||||
const (
|
||||
NOT_SET = 0
|
||||
DEVELOP = 1
|
||||
TESTING = 2
|
||||
STAGING = 3
|
||||
PRODUCT = 4
|
||||
NOT_SET = "not-set"
|
||||
DEVELOP = "develop"
|
||||
TESTING = "testing"
|
||||
STAGING = "staging"
|
||||
PRODUCT = "product"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -22,7 +22,7 @@ var (
|
||||
)
|
||||
|
||||
// Set sets the mode for current application.
|
||||
func Set(mode int) {
|
||||
func Set(mode string) {
|
||||
currentMode = mode
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ func SetProduct() {
|
||||
}
|
||||
|
||||
// Mode returns current application mode set.
|
||||
func Mode() int {
|
||||
func Mode() string {
|
||||
// If current mode is not set, do this auto check.
|
||||
if currentMode == NOT_SET {
|
||||
if gfile.MainPkgPath() != "" {
|
||||
|
||||
Reference in New Issue
Block a user