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.
14 // TCPConn is an implementation of the Conn interface for TCP network
20 func newTCPConn(fd
*netFD
) *TCPConn
{
21 return &TCPConn
{conn
{fd
}}
24 // ReadFrom implements the io.ReaderFrom ReadFrom method.
25 func (c
*TCPConn
) ReadFrom(r io
.Reader
) (int64, error
) {
26 return genericReadFrom(c
, r
)
29 // CloseRead shuts down the reading side of the TCP connection.
30 // Most callers should just use Close.
31 func (c
*TCPConn
) CloseRead() error
{
35 return c
.fd
.closeRead()
38 // CloseWrite shuts down the writing side of the TCP connection.
39 // Most callers should just use Close.
40 func (c
*TCPConn
) CloseWrite() error
{
44 return c
.fd
.closeWrite()
47 // SetLinger sets the behavior of Close on a connection which still
48 // has data waiting to be sent or to be acknowledged.
50 // If sec < 0 (the default), the operating system finishes sending the
51 // data in the background.
53 // If sec == 0, the operating system discards any unsent or
54 // unacknowledged data.
56 // If sec > 0, the data is sent in the background as with sec < 0. On
57 // some operating systems after sec seconds have elapsed any remaining
58 // unsent data may be discarded.
59 func (c
*TCPConn
) SetLinger(sec
int) error
{
63 // SetKeepAlive sets whether the operating system should send
64 // keepalive messages on the connection.
65 func (c
*TCPConn
) SetKeepAlive(keepalive
bool) error
{
69 return setKeepAlive(c
.fd
, keepalive
)
72 // SetKeepAlivePeriod sets period between keep alives.
73 func (c
*TCPConn
) SetKeepAlivePeriod(d time
.Duration
) error
{
77 return setKeepAlivePeriod(c
.fd
, d
)
80 // SetNoDelay controls whether the operating system should delay
81 // packet transmission in hopes of sending fewer packets (Nagle's
82 // algorithm). The default is true (no delay), meaning that data is
83 // sent as soon as possible after a Write.
84 func (c
*TCPConn
) SetNoDelay(noDelay
bool) error
{
88 // DialTCP connects to the remote address raddr on the network net,
89 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
90 // used as the local address for the connection.
91 func DialTCP(net
string, laddr
, raddr
*TCPAddr
) (*TCPConn
, error
) {
92 return dialTCP(net
, laddr
, raddr
, noDeadline
)
95 func dialTCP(net
string, laddr
, raddr
*TCPAddr
, deadline time
.Time
) (*TCPConn
, error
) {
96 if !deadline
.IsZero() {
97 panic("net.dialTCP: deadline not implemented on Plan 9")
100 case "tcp", "tcp4", "tcp6":
102 return nil, &OpError
{"dial", net
, raddr
, UnknownNetworkError(net
)}
105 return nil, &OpError
{"dial", net
, nil, errMissingAddress
}
107 fd
, err
:= dialPlan9(net
, laddr
, raddr
)
111 return newTCPConn(fd
), nil
114 // TCPListener is a TCP network listener. Clients should typically
115 // use variables of type Listener instead of assuming TCP.
116 type TCPListener
struct {
120 // AcceptTCP accepts the next incoming call and returns the new
122 func (l
*TCPListener
) AcceptTCP() (*TCPConn
, error
) {
123 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
124 return nil, syscall
.EINVAL
126 fd
, err
:= l
.fd
.acceptPlan9()
130 return newTCPConn(fd
), nil
133 // Accept implements the Accept method in the Listener interface; it
134 // waits for the next call and returns a generic Conn.
135 func (l
*TCPListener
) Accept() (Conn
, error
) {
136 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
137 return nil, syscall
.EINVAL
139 c
, err
:= l
.AcceptTCP()
146 // Close stops listening on the TCP address.
147 // Already Accepted connections are not closed.
148 func (l
*TCPListener
) Close() error
{
149 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
150 return syscall
.EINVAL
152 if _
, err
:= l
.fd
.ctl
.WriteString("hangup"); err
!= nil {
154 return &OpError
{"close", l
.fd
.ctl
.Name(), l
.fd
.laddr
, err
}
156 return l
.fd
.ctl
.Close()
159 // Addr returns the listener's network address, a *TCPAddr.
160 func (l
*TCPListener
) Addr() Addr
{ return l
.fd
.laddr
}
162 // SetDeadline sets the deadline associated with the listener.
163 // A zero time value disables the deadline.
164 func (l
*TCPListener
) SetDeadline(t time
.Time
) error
{
165 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
166 return syscall
.EINVAL
168 return l
.fd
.setDeadline(t
)
171 // File returns a copy of the underlying os.File, set to blocking
172 // mode. It is the caller's responsibility to close f when finished.
173 // Closing l does not affect f, and closing f does not affect l.
175 // The returned os.File's file descriptor is different from the
176 // connection's. Attempting to change properties of the original
177 // using this duplicate may or may not have the desired effect.
178 func (l
*TCPListener
) File() (f
*os
.File
, err error
) { return l
.dup() }
180 // ListenTCP announces on the TCP address laddr and returns a TCP
181 // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
182 // port of 0, ListenTCP will choose an available port. The caller can
183 // use the Addr method of TCPListener to retrieve the chosen address.
184 func ListenTCP(net
string, laddr
*TCPAddr
) (*TCPListener
, error
) {
186 case "tcp", "tcp4", "tcp6":
188 return nil, &OpError
{"listen", net
, laddr
, UnknownNetworkError(net
)}
193 fd
, err
:= listenPlan9(net
, laddr
)
197 return &TCPListener
{fd
}, nil