1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
15 // BUG(mikio): On Windows, the File method of TCPListener is not
18 // TCPAddr represents the address of a TCP end point.
22 Zone
string // IPv6 scoped addressing zone
25 // Network returns the address's network name, "tcp".
26 func (a
*TCPAddr
) Network() string { return "tcp" }
28 func (a
*TCPAddr
) String() string {
32 ip
:= ipEmptyString(a
.IP
)
34 return JoinHostPort(ip
+"%"+a
.Zone
, itoa(a
.Port
))
36 return JoinHostPort(ip
, itoa(a
.Port
))
39 func (a
*TCPAddr
) isWildcard() bool {
40 if a
== nil || a
.IP
== nil {
43 return a
.IP
.IsUnspecified()
46 func (a
*TCPAddr
) opAddr() Addr
{
53 // ResolveTCPAddr parses addr as a TCP address of the form "host:port"
54 // or "[ipv6-host%zone]:port" and resolves a pair of domain name and
55 // port name on the network net, which must be "tcp", "tcp4" or
56 // "tcp6". A literal address or host name for IPv6 must be enclosed
57 // in square brackets, as in "[::1]:80", "[ipv6-host]:http" or
58 // "[ipv6-host%zone]:80".
60 // Resolving a hostname is not recommended because this returns at most
61 // one of its IP addresses.
62 func ResolveTCPAddr(net
, addr
string) (*TCPAddr
, error
) {
64 case "tcp", "tcp4", "tcp6":
65 case "": // a hint wildcard for Go 1.0 undocumented behavior
68 return nil, UnknownNetworkError(net
)
70 addrs
, err
:= DefaultResolver
.internetAddrList(context
.Background(), net
, addr
)
74 return addrs
.first(isIPv4
).(*TCPAddr
), nil
77 // TCPConn is an implementation of the Conn interface for TCP network
83 // ReadFrom implements the io.ReaderFrom ReadFrom method.
84 func (c
*TCPConn
) ReadFrom(r io
.Reader
) (int64, error
) {
86 return 0, syscall
.EINVAL
88 n
, err
:= c
.readFrom(r
)
89 if err
!= nil && err
!= io
.EOF
{
90 err
= &OpError
{Op
: "readfrom", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
95 // CloseRead shuts down the reading side of the TCP connection.
96 // Most callers should just use Close.
97 func (c
*TCPConn
) CloseRead() error
{
101 if err
:= c
.fd
.closeRead(); err
!= nil {
102 return &OpError
{Op
: "close", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
107 // CloseWrite shuts down the writing side of the TCP connection.
108 // Most callers should just use Close.
109 func (c
*TCPConn
) CloseWrite() error
{
111 return syscall
.EINVAL
113 if err
:= c
.fd
.closeWrite(); err
!= nil {
114 return &OpError
{Op
: "close", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
119 // SetLinger sets the behavior of Close on a connection which still
120 // has data waiting to be sent or to be acknowledged.
122 // If sec < 0 (the default), the operating system finishes sending the
123 // data in the background.
125 // If sec == 0, the operating system discards any unsent or
126 // unacknowledged data.
128 // If sec > 0, the data is sent in the background as with sec < 0. On
129 // some operating systems after sec seconds have elapsed any remaining
130 // unsent data may be discarded.
131 func (c
*TCPConn
) SetLinger(sec
int) error
{
133 return syscall
.EINVAL
135 if err
:= setLinger(c
.fd
, sec
); err
!= nil {
136 return &OpError
{Op
: "set", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
141 // SetKeepAlive sets whether the operating system should send
142 // keepalive messages on the connection.
143 func (c
*TCPConn
) SetKeepAlive(keepalive
bool) error
{
145 return syscall
.EINVAL
147 if err
:= setKeepAlive(c
.fd
, keepalive
); err
!= nil {
148 return &OpError
{Op
: "set", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
153 // SetKeepAlivePeriod sets period between keep alives.
154 func (c
*TCPConn
) SetKeepAlivePeriod(d time
.Duration
) error
{
156 return syscall
.EINVAL
158 if err
:= setKeepAlivePeriod(c
.fd
, d
); err
!= nil {
159 return &OpError
{Op
: "set", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
164 // SetNoDelay controls whether the operating system should delay
165 // packet transmission in hopes of sending fewer packets (Nagle's
166 // algorithm). The default is true (no delay), meaning that data is
167 // sent as soon as possible after a Write.
168 func (c
*TCPConn
) SetNoDelay(noDelay
bool) error
{
170 return syscall
.EINVAL
172 if err
:= setNoDelay(c
.fd
, noDelay
); err
!= nil {
173 return &OpError
{Op
: "set", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
178 func newTCPConn(fd
*netFD
) *TCPConn
{
179 c
:= &TCPConn
{conn
{fd
}}
180 setNoDelay(c
.fd
, true)
184 // DialTCP connects to the remote address raddr on the network net,
185 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
186 // used as the local address for the connection.
187 func DialTCP(net
string, laddr
, raddr
*TCPAddr
) (*TCPConn
, error
) {
189 case "tcp", "tcp4", "tcp6":
191 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: UnknownNetworkError(net
)}
194 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: nil, Err
: errMissingAddress
}
196 c
, err
:= dialTCP(context
.Background(), net
, laddr
, raddr
)
198 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: err
}
203 // TCPListener is a TCP network listener. Clients should typically
204 // use variables of type Listener instead of assuming TCP.
205 type TCPListener
struct {
209 // AcceptTCP accepts the next incoming call and returns the new
211 func (l
*TCPListener
) AcceptTCP() (*TCPConn
, error
) {
213 return nil, syscall
.EINVAL
217 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
222 // Accept implements the Accept method in the Listener interface; it
223 // waits for the next call and returns a generic Conn.
224 func (l
*TCPListener
) Accept() (Conn
, error
) {
226 return nil, syscall
.EINVAL
230 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
235 // Close stops listening on the TCP address.
236 // Already Accepted connections are not closed.
237 func (l
*TCPListener
) Close() error
{
239 return syscall
.EINVAL
241 if err
:= l
.close(); err
!= nil {
242 return &OpError
{Op
: "close", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
247 // Addr returns the listener's network address, a *TCPAddr.
248 // The Addr returned is shared by all invocations of Addr, so
250 func (l
*TCPListener
) Addr() Addr
{ return l
.fd
.laddr
}
252 // SetDeadline sets the deadline associated with the listener.
253 // A zero time value disables the deadline.
254 func (l
*TCPListener
) SetDeadline(t time
.Time
) error
{
256 return syscall
.EINVAL
258 if err
:= l
.fd
.setDeadline(t
); err
!= nil {
259 return &OpError
{Op
: "set", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
264 // File returns a copy of the underlying os.File, set to blocking
265 // mode. It is the caller's responsibility to close f when finished.
266 // Closing l does not affect f, and closing f does not affect l.
268 // The returned os.File's file descriptor is different from the
269 // connection's. Attempting to change properties of the original
270 // using this duplicate may or may not have the desired effect.
271 func (l
*TCPListener
) File() (f
*os
.File
, err error
) {
273 return nil, syscall
.EINVAL
277 return nil, &OpError
{Op
: "file", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
282 // ListenTCP announces on the TCP address laddr and returns a TCP
283 // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
284 // port of 0, ListenTCP will choose an available port. The caller can
285 // use the Addr method of TCPListener to retrieve the chosen address.
286 func ListenTCP(net
string, laddr
*TCPAddr
) (*TCPListener
, error
) {
288 case "tcp", "tcp4", "tcp6":
290 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(net
)}
295 ln
, err
:= listenTCP(context
.Background(), net
, laddr
)
297 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}