/
gtcp_func.go
139 lines (125 loc) · 4.29 KB
/
gtcp_func.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// 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.
package gtcp
import (
"crypto/rand"
"crypto/tls"
"net"
"time"
"github.com/gogf/gf/os/gfile"
)
const (
defaultConnTimeout = 30 * time.Second // Default connection timeout.
defaultRetryInternal = 100 * time.Millisecond // Default retry interval.
defaultReadBufferSize = 128 // (Byte) Buffer size for reading.
)
type Retry struct {
Count int // Retry count.
Interval time.Duration // Retry interval.
}
// 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 := defaultConnTimeout
if len(timeout) > 0 {
d = timeout[0]
}
return net.DialTimeout("tcp", addr, d)
}
// 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: defaultConnTimeout,
}
if len(timeout) > 0 {
dialer.Timeout = timeout[0]
}
return tls.DialWithDialer(dialer, "tcp", addr, tlsConfig)
}
// 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, timeout...)
}
// 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
}
defer conn.Close()
return conn.Send(data, retry...)
}
// 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, length, retry...)
}
// 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
}
defer conn.Close()
return conn.SendWithTimeout(data, timeout, retry...)
}
// 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
}
defer conn.Close()
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
}
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
return true
}
return false
}
// 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 {
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
}
tlsConfig := &tls.Config{}
tlsConfig.Certificates = []tls.Certificate{crt}
tlsConfig.Time = time.Now
tlsConfig.Rand = rand.Reader
return tlsConfig, nil
}