-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtcp_server.go
115 lines (92 loc) · 1.99 KB
/
tcp_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
package transport
import (
"context"
"net"
)
type TCPServer struct {
ReuseServer
listeners []*net.TCPListener
}
func (t *TCPServer) Bind(addr net.Addr) error {
Assert(t.listeners == nil)
// 监听地址为nil, 系统分配端口
random := addr == nil
if random {
t.ConcurrentNumber = 1
addr, _ = net.ResolveTCPAddr("tcp", ":0")
}
config := net.ListenConfig{
Control: t.GetSetOptFunc(),
}
t.ctx, t.cancel = context.WithCancel(context.Background())
number := t.ComputeConcurrentNumber()
for i := 0; i < number; i++ {
listen, err := config.Listen(t.ctx, "tcp", addr.String())
if err != nil {
t.Close()
return err
}
t.listeners = append(t.listeners, listen.(*net.TCPListener))
if random {
t.setListenAddr(listen.Addr())
} else {
t.setListenAddr(addr)
}
}
return nil
}
func (t *TCPServer) Accept() {
Assert(t.handler != nil)
Assert(len(t.listeners) > 0)
for _, listener := range t.listeners {
go t.doAccept(listener)
}
}
func (t *TCPServer) doAccept(listener *net.TCPListener) {
for t.ctx.Err() == nil {
conn, err := listener.AcceptTCP()
if err != nil {
println(err.Error())
continue
}
go readDataFromTCPConn(t.ctx, NewConn(conn), t.handler)
}
}
func (t *TCPServer) Close() {
for _, listener := range t.listeners {
_ = listener.Close()
}
t.listeners = nil
t.transport.Close()
}
func readDataFromTCPConn(ctx context.Context, conn net.Conn, handler Handler) {
var receiveBuffer []byte
if handler != nil {
receiveBuffer = handler.OnConnected(conn)
}
if receiveBuffer == nil {
receiveBuffer = make([]byte, DefaultTCPRecvBufferSize)
}
var n int
var err error
var buffer []byte
for ctx.Err() == nil {
if buffer == nil {
buffer = receiveBuffer
}
n, err = conn.Read(buffer)
if err != nil {
if err.Error() != "EOF" {
println(err.Error())
}
break
}
if n > 0 && handler != nil {
buffer = handler.OnPacket(conn, buffer[:n])
}
}
_ = conn.Close()
if handler != nil {
handler.OnDisConnected(conn, err)
}
}