Source file
src/net/tcpsock.go
Documentation: net
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 c, err := dialTCP(context.Background(), network, laddr, raddr)
216 if err != nil {
217 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
218 }
219 return c, nil
220 }
221
222
223
224 type TCPListener struct {
225 fd *netFD
226 }
227
228
229
230
231
232
233 func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
234 if !l.ok() {
235 return nil, syscall.EINVAL
236 }
237 return newRawListener(l.fd)
238 }
239
240
241
242 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
243 if !l.ok() {
244 return nil, syscall.EINVAL
245 }
246 c, err := l.accept()
247 if err != nil {
248 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
249 }
250 return c, nil
251 }
252
253
254
255 func (l *TCPListener) Accept() (Conn, error) {
256 if !l.ok() {
257 return nil, syscall.EINVAL
258 }
259 c, err := l.accept()
260 if err != nil {
261 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
262 }
263 return c, nil
264 }
265
266
267
268 func (l *TCPListener) Close() error {
269 if !l.ok() {
270 return syscall.EINVAL
271 }
272 if err := l.close(); err != nil {
273 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
274 }
275 return nil
276 }
277
278
279
280
281 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
282
283
284
285 func (l *TCPListener) SetDeadline(t time.Time) error {
286 if !l.ok() {
287 return syscall.EINVAL
288 }
289 if err := l.fd.pfd.SetDeadline(t); err != nil {
290 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
291 }
292 return nil
293 }
294
295
296
297
298
299
300
301
302 func (l *TCPListener) File() (f *os.File, err error) {
303 if !l.ok() {
304 return nil, syscall.EINVAL
305 }
306 f, err = l.file()
307 if err != nil {
308 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
309 }
310 return
311 }
312
313
314
315
316
317
318
319
320
321
322 func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
323 switch network {
324 case "tcp", "tcp4", "tcp6":
325 default:
326 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
327 }
328 if laddr == nil {
329 laddr = &TCPAddr{}
330 }
331 ln, err := listenTCP(context.Background(), network, laddr)
332 if err != nil {
333 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
334 }
335 return ln, nil
336 }
337
View as plain text