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