-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcp_transport.go
127 lines (112 loc) · 3.67 KB
/
tcp_transport.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
package raft
import (
"errors"
"github.com/hashicorp/go-hclog"
"io"
"net"
"time"
)
var (
errNotAdvertisable = errors.New("local bind address is not advertisable")
errNotTCP = errors.New("local address is not a TCP address")
)
// TCPStreamLayer implements StreamLayer interface for plain TCP.
type TCPStreamLayer struct {
advertise net.Addr /*广播的地址*/
listener *net.TCPListener /*监控的地址*/
}
// NewTCPTransport returns a NetworkTransport that is built on top of
// a TCP streaming transport layer.
func NewTCPTransport(
bindAddr string,
advertise net.Addr,
maxPool int,
timeout time.Duration,
logOutput io.Writer,
) (*NetworkTransport, error) {
return newTCPTransport(bindAddr, advertise, func(stream StreamLayer) *NetworkTransport {
return NewNetworkTransport(stream, maxPool, timeout, logOutput)
})
}
// NewTCPTransportWithLogger returns a NetworkTransport that is built on top of
// a TCP streaming transport layer, with log output going to the supplied Logger
func NewTCPTransportWithLogger(
bindAddr string,
advertise net.Addr,
maxPool int,
timeout time.Duration,
logger hclog.Logger,
) (*NetworkTransport, error) {
return newTCPTransport(bindAddr, advertise, func(stream StreamLayer) *NetworkTransport {
return NewNetworkTransportWithLogger(stream, maxPool, timeout, logger)
})
}
// NewTCPTransportWithConfig returns a NetworkTransport that is built on top of
// a TCP streaming transport layer, using the given config struct.
func NewTCPTransportWithConfig(
bindAddr string,
advertise net.Addr,
config *NetworkTransportConfig,
) (*NetworkTransport, error) {
return newTCPTransport(bindAddr, advertise, func(stream StreamLayer) *NetworkTransport {
config.Stream = stream
return NewNetworkTransportWithConfig(config)
})
}
func newTCPTransport(bindAddr string,
advertise net.Addr, /* net.Addr 是个接口 又协议名(tcp,udp)和地址(127.0.0.1:80)组成, *net.TCPAddr和*net.UDPAddr实现了这个接口 */
transportCreator func(stream StreamLayer) *NetworkTransport) (*NetworkTransport, error) {
// Try to bind
list, err := net.Listen("tcp", bindAddr)
if err != nil {
return nil, err
}
// Create stream
// stream 感觉就像是个打开了(还没有)个tcp socket
stream := &TCPStreamLayer{
advertise: advertise,
listener: list.(*net.TCPListener),
}
// Verify that we have a usable advertise address
//net.TCPAddr 可以认为是有ip(127.0.0.1)和端口(80)组成
//*net.TCPAddr
addr, ok := stream.Addr().(*net.TCPAddr)
if !ok {
list.Close()
return nil, errNotTCP
}
//IsUnspecified判断ip是否是 0.0.0.0 这样的地址
//此处 如果我们监听的地址是 0.0.0.0:8080 而没有提供广播地址则会在此出错
if addr.IP.IsUnspecified() {
list.Close()
return nil, errNotAdvertisable
}
// Create the network transport
trans := transportCreator(stream)
return trans, nil
}
// Dial implements the StreamLayer interface.
//发起tcp连接
func (t *TCPStreamLayer) Dial(address ServerAddress, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("tcp", string(address), timeout)
}
// Accept implements the net.Listener interface.
//接收tcp请求
func (t *TCPStreamLayer) Accept() (c net.Conn, err error) {
return t.listener.Accept()
}
// Close implements the net.Listener interface.
//关闭tcp请求
func (t *TCPStreamLayer) Close() (err error) {
return t.listener.Close()
}
// Addr implements the net.Listener interface.
func (t *TCPStreamLayer) Addr() net.Addr {
// Use an advertise addr if provided
//如果提供了 建议广播的地址 则使用这个
if t.advertise != nil {
return t.advertise
}
//如果没有提供广播地址 则使用bind tcp的服务地址
return t.listener.Addr()
}