-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsocket.go
146 lines (136 loc) · 3.47 KB
/
socket.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
145
146
/*
* @Author: 时光弧线
* @Date: 2017-12-30 11:55:41
* @Last Modified by: 时光弧线
* @Last Modified time: 2017-12-30 13:22:40
*/
package tcplibrary
import (
"crypto/tls"
"errors"
"fmt"
"net"
"time"
)
/* tcp 连接 */
// TCPServer tcp服务端对象
type TCPServer struct {
*TCPLibrary
isListener bool // 是否已监听
}
// NewTCPServer 创建一个server实例
func (t *TCPLibrary) NewTCPServer() *TCPServer {
return &TCPServer{
TCPLibrary: t,
isListener: false,
}
}
// ListenAndServe 开始tcp监听
func (tcp *TCPServer) ListenAndServe(address string) error {
if tcp.isListener == true {
return errors.New("已调用监听端口")
}
if address == "" {
return errors.New("监听地址不能为空")
}
// 开启tcp监听
addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
globalLogger.Errorf(err.Error())
return err
}
listen, err := net.ListenTCP("tcp", addr)
if err != nil {
return err
}
return tcp.Serve(listen)
}
// ListenAndServeTLS 开始tcp监听 tls
func (tcp *TCPServer) ListenAndServeTLS(address, certFile, keyFile string) error {
if tcp.isListener == true {
return errors.New("已调用监听端口")
}
if address == "" {
return errors.New("监听地址不能为空")
}
// 开启tcp监听
addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
globalLogger.Errorf(err.Error())
return err
}
listen, err := net.ListenTCP("tcp", addr)
if err != nil {
return err
}
// 证书配置
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return err
}
config := &tls.Config{Certificates: []tls.Certificate{cert}}
tlsListener := tls.NewListener(listen, config)
return tcp.Serve(tlsListener)
}
// Serve 开启服务
func (tcp *TCPServer) Serve(listen net.Listener) error {
// 判断是否设置读超时
if tcp.readDeadline == 0 {
tcp.readDeadline = DefaultReadDeadline
}
// 监听对象赋值给当前对象,并将isListener设为true
tcp.listener = listen
tcp.isListener = true
// 打印开启tcp服务
globalLogger.Infof("tcp socket start, net %s addr %s", listen.Addr().Network(), listen.Addr().String())
// 开始接收客户端连接
for {
select {
case <-tcp.ctx.Done():
globalLogger.Infof("tcp Serve收到ctx.Done()")
return nil
default:
tcpConn, err := tcp.listener.Accept()
if err != nil {
globalLogger.Errorf(err.Error())
continue
}
// 创建一个Conn对象
conn := &Conn{
Conn: tcpConn,
connType: TCPSocketType,
packet: tcp.packet,
}
// 获取客户端id
serverSocket, ok := tcp.socket.(ServerSocket)
if ok == false {
// 如果建立连接函数返回false,则关闭连接
tcp.socket.OnClose(conn, fmt.Errorf("%s", "转换为ServerSocket错误")) // 通知关闭
err = conn.Close() // 关闭连接
if err != nil {
globalLogger.Errorf(err.Error())
}
break
}
clientID := serverSocket.GetClientID()
conn.clientID = clientID
// 通知连接创建后函数
err = tcp.socket.OnConnect(conn)
if err != nil {
// 如果建立连接函数返回false,则关闭连接
tcp.socket.OnClose(conn, err) // 通知关闭
err = conn.Close() // 关闭连接
if err != nil {
globalLogger.Errorf(err.Error())
}
break
}
tcp.clients.Store(clientID, conn)
// 设置超时
conn.SetReadDeadline(time.Now().Add(tcp.readDeadline))
// 开启一个协程处理数据接收
go tcp.handleConn(conn)
}
}
return nil
}