-
Notifications
You must be signed in to change notification settings - Fork 0
/
gtcp_server.go
144 lines (133 loc) · 3.79 KB
/
gtcp_server.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
140
141
142
143
144
package gtcp
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"strings"
"sync"
"github.com/camry/g/gerrors/gcode"
"github.com/camry/g/gerrors/gerror"
)
const (
// FreePortAddress 使用随机端口标记服务器监听。
FreePortAddress = ":0"
)
// Server 定义 TCP 服务包装器。
type Server struct {
err error
mu sync.Mutex // 用于 Server.listen 并发安全。
listen net.Listener // 网络监听器。
network string // 服务器网络协议。
address string // 服务器监听地址。
handler func(*Conn) // 连接处理器。
tlsConfig *tls.Config // TLS 配置。
}
// NewServer 新建 TCP 服务器。
func NewServer(address string, handler func(*Conn)) *Server {
srv := &Server{
network: "tcp",
address: address,
handler: handler,
}
srv.err = srv.listener()
return srv
}
// NewServerTLS 新建 TCP TLS 服务器。
func NewServerTLS(address string, tlsConfig *tls.Config, handler func(*Conn)) *Server {
srv := &Server{
network: "tcp",
address: address,
handler: handler,
tlsConfig: tlsConfig,
}
srv.err = srv.listener()
return srv
}
// listener 网络监听器。
func (s *Server) listener() (err error) {
if s.handler == nil {
err = gerror.NewCode(gcode.CodeMissingConfiguration, "start running failed: socket handler not defined")
return
}
if s.tlsConfig != nil {
// TLS Server
s.mu.Lock()
s.listen, err = tls.Listen(s.network, s.address, s.tlsConfig)
s.mu.Unlock()
if err != nil {
err = gerror.Wrapf(err, `tls.Listen failed for address "%s"`, s.address)
return
}
} else {
// Normal Server
var tcpAddr *net.TCPAddr
if tcpAddr, err = net.ResolveTCPAddr(s.network, s.address); err != nil {
err = gerror.Wrapf(err, `net.ResolveTCPAddr failed for address "%s"`, s.address)
return err
}
s.mu.Lock()
s.listen, err = net.ListenTCP(s.network, tcpAddr)
s.mu.Unlock()
if err != nil {
err = gerror.Wrapf(err, `net.ListenTCP failed for address "%s"`, s.address)
return err
}
}
return nil
}
// Close 关闭 TCP 服务器。
func (s *Server) Close(ctx context.Context) error {
s.mu.Lock()
defer s.mu.Unlock()
if s.listen == nil {
return nil
}
return s.listen.Close()
}
// Run 启动 TCP 服务器。
func (s *Server) Run(ctx context.Context) (err error) {
if s.err != nil {
return s.err
}
if s.listen == nil {
err = errors.New("gtcp start running failed: socket Listener not defined")
return
}
if s.handler == nil {
err = errors.New("gtcp start running failed: socket handler not defined")
return
}
// Listening loop.
for {
var conn net.Conn
if conn, err = s.listen.Accept(); err != nil {
err = gerror.Wrapf(err, `Listener.Accept failed`)
return err
} else if conn != nil {
go s.handler(NewConnByNetConn(conn))
}
}
}
// GetListenedAddress 获取当前服务器监听地址。
func (s *Server) GetListenedAddress() string {
if !strings.Contains(s.address, FreePortAddress) {
return s.address
}
var (
address = s.address
listenedPort = s.GetListenedPort()
)
address = strings.Replace(address, FreePortAddress, fmt.Sprintf(`:%d`, listenedPort), -1)
return address
}
// GetListenedPort 获取当前服务器监听端口。
func (s *Server) GetListenedPort() int {
s.mu.Lock()
defer s.mu.Unlock()
if ln := s.listen; ln != nil {
return ln.Addr().(*net.TCPAddr).Port
}
return -1
}