Source file src/pkg/net/tcpsock.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "io"
10 "os"
11 "syscall"
12 "time"
13 )
14
15
16
17
18
19 type TCPAddr struct {
20 IP IP
21 Port int
22 Zone string
23 }
24
25
26 func (a *TCPAddr) Network() string { return "tcp" }
27
28 func (a *TCPAddr) String() string {
29 if a == nil {
30 return "<nil>"
31 }
32 ip := ipEmptyString(a.IP)
33 if a.Zone != "" {
34 return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
35 }
36 return JoinHostPort(ip, itoa(a.Port))
37 }
38
39 func (a *TCPAddr) isWildcard() bool {
40 if a == nil || a.IP == nil {
41 return true
42 }
43 return a.IP.IsUnspecified()
44 }
45
46 func (a *TCPAddr) opAddr() Addr {
47 if a == nil {
48 return nil
49 }
50 return a
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 func ResolveTCPAddr(network, address string) (*TCPAddr, error) {
69 switch network {
70 case "tcp", "tcp4", "tcp6":
71 case "":
72 network = "tcp"
73 default:
74 return nil, UnknownNetworkError(network)
75 }
76 addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
77 if err != nil {
78 return nil, err
79 }
80 return addrs.forResolve(network, address).(*TCPAddr), nil
81 }
82
83
84
85 type TCPConn struct {
86 conn
87 }
88
89
90
91 func (c *TCPConn) SyscallConn() (syscall.RawConn, error) {
92 if !c.ok() {
93 return nil, syscall.EINVAL
94 }
95 return newRawConn(c.fd)
96 }
97
98
99 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
100 if !c.ok() {
101 return 0, syscall.EINVAL
102 }
103 n, err := c.readFrom(r)
104 if err != nil && err != io.EOF {
105 err = &OpError{Op: "readfrom", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
106 }
107 return n, err
108 }
109
110
111
112 func (c *TCPConn) CloseRead() error {
113 if !c.ok() {
114 return syscall.EINVAL
115 }
116 if err := c.fd.closeRead(); err != nil {
117 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
118 }
119 return nil
120 }
121
122
123
124 func (c *TCPConn) CloseWrite() error {
125 if !c.ok() {
126 return syscall.EINVAL
127 }
128 if err := c.fd.closeWrite(); err != nil {
129 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
130 }
131 return nil
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146 func (c *TCPConn) SetLinger(sec int) error {
147 if !c.ok() {
148 return syscall.EINVAL
149 }
150 if err := setLinger(c.fd, sec); err != nil {
151 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
152 }
153 return nil
154 }
155
156
157
158 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
159 if !c.ok() {
160 return syscall.EINVAL
161 }
162 if err := setKeepAlive(c.fd, keepalive); err != nil {
163 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
164 }
165 return nil
166 }
167
168
169 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
170 if !c.ok() {
171 return syscall.EINVAL
172 }
173 if err := setKeepAlivePeriod(c.fd, d); err != nil {
174 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
175 }
176 return nil
177 }
178
179
180
181
182
183 func (c *TCPConn) SetNoDelay(noDelay bool) error {
184 if !c.ok() {
185 return syscall.EINVAL
186 }
187 if err := setNoDelay(c.fd, noDelay); err != nil {
188 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
189 }
190 return nil
191 }
192
193 func newTCPConn(fd *netFD) *TCPConn {
194 c := &TCPConn{conn{fd}}
195 setNoDelay(c.fd, true)
196 return c
197 }
198
199
200
201
202
203
204
205
206 func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
207 switch network {
208 case "tcp", "tcp4", "tcp6":
209 default:
210 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
211 }
212 if raddr == nil {
213 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
214 }
215 sd := &sysDialer{network: network, address: raddr.String()}
216 c, err := sd.dialTCP(context.Background(), laddr, raddr)
217 if err != nil {
218 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
219 }
220 return c, nil
221 }
222
223
224
225 type TCPListener struct {
226 fd *netFD
227 lc ListenConfig
228 }
229
230
231
232
233
234
235 func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
236 if !l.ok() {
237 return nil, syscall.EINVAL
238 }
239 return newRawListener(l.fd)
240 }
241
242
243
244 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
245 if !l.ok() {
246 return nil, syscall.EINVAL
247 }
248 c, err := l.accept()
249 if err != nil {
250 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
251 }
252 return c, nil
253 }
254
255
256
257 func (l *TCPListener) Accept() (Conn, error) {
258 if !l.ok() {
259 return nil, syscall.EINVAL
260 }
261 c, err := l.accept()
262 if err != nil {
263 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
264 }
265 return c, nil
266 }
267
268
269
270 func (l *TCPListener) Close() error {
271 if !l.ok() {
272 return syscall.EINVAL
273 }
274 if err := l.close(); err != nil {
275 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
276 }
277 return nil
278 }
279
280
281
282
283 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
284
285
286
287 func (l *TCPListener) SetDeadline(t time.Time) error {
288 if !l.ok() {
289 return syscall.EINVAL
290 }
291 if err := l.fd.pfd.SetDeadline(t); err != nil {
292 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
293 }
294 return nil
295 }
296
297
298
299
300
301
302
303
304 func (l *TCPListener) File() (f *os.File, err error) {
305 if !l.ok() {
306 return nil, syscall.EINVAL
307 }
308 f, err = l.file()
309 if err != nil {
310 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
311 }
312 return
313 }
314
315
316
317
318
319
320
321
322
323
324 func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
325 switch network {
326 case "tcp", "tcp4", "tcp6":
327 default:
328 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
329 }
330 if laddr == nil {
331 laddr = &TCPAddr{}
332 }
333 sl := &sysListener{network: network, address: laddr.String()}
334 ln, err := sl.listenTCP(context.Background(), laddr)
335 if err != nil {
336 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
337 }
338 return ln, nil
339 }
340
View as plain text