// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package netimport ()// BUG(mikio): On JS and Windows, the File method of TCPConn and// TCPListener is not implemented.// TCPAddr represents the address of a TCP end point.typeTCPAddrstruct { IP IP Port int Zone string// IPv6 scoped addressing zone}// AddrPort returns the [TCPAddr] a as a [netip.AddrPort].//// If a.Port does not fit in a uint16, it's silently truncated.//// If a is nil, a zero value is returned.func ( *TCPAddr) () netip.AddrPort {if == nil {returnnetip.AddrPort{} } , := netip.AddrFromSlice(.IP) = .WithZone(.Zone)returnnetip.AddrPortFrom(, uint16(.Port))}// Network returns the address's network name, "tcp".func ( *TCPAddr) () string { return"tcp" }func ( *TCPAddr) () string {if == nil {return"<nil>" } := ipEmptyString(.IP)if .Zone != "" {returnJoinHostPort(+"%"+.Zone, itoa.Itoa(.Port)) }returnJoinHostPort(, itoa.Itoa(.Port))}func ( *TCPAddr) () bool {if == nil || .IP == nil {returntrue }return .IP.IsUnspecified()}func ( *TCPAddr) () Addr {if == nil {returnnil }return}// ResolveTCPAddr returns an address of TCP end point.//// The network must be a TCP network name.//// If the host in the address parameter is not a literal IP address or// the port is not a literal port number, ResolveTCPAddr resolves the// address to an address of TCP end point.// Otherwise, it parses the address as a pair of literal IP address// and port number.// The address parameter can use a host name, but this is not// recommended, because it will return at most one of the host name's// IP addresses.//// See func [Dial] for a description of the network and address// parameters.func (, string) (*TCPAddr, error) {switch {case"tcp", "tcp4", "tcp6":case"": // a hint wildcard for Go 1.0 undocumented behavior = "tcp"default:returnnil, UnknownNetworkError() } , := DefaultResolver.internetAddrList(context.Background(), , )if != nil {returnnil, }return .forResolve(, ).(*TCPAddr), nil}// TCPAddrFromAddrPort returns addr as a [TCPAddr]. If addr.IsValid() is false,// then the returned TCPAddr will contain a nil IP field, indicating an// address family-agnostic unspecified address.func ( netip.AddrPort) *TCPAddr {return &TCPAddr{IP: .Addr().AsSlice(),Zone: .Addr().Zone(),Port: int(.Port()), }}// TCPConn is an implementation of the [Conn] interface for TCP network// connections.typeTCPConnstruct {conn}// KeepAliveConfig contains TCP keep-alive options.//// If the Idle, Interval, or Count fields are zero, a default value is chosen.// If a field is negative, the corresponding socket-level option will be left unchanged.//// Note that prior to Windows 10 version 1709, neither setting Idle and Interval// separately nor changing Count (which is usually 10) is supported.// Therefore, it's recommended to set both Idle and Interval to non-negative values// in conjunction with a -1 for Count on those old Windows if you intend to customize// the TCP keep-alive settings.// By contrast, if only one of Idle and Interval is set to a non-negative value,// the other will be set to the system default value, and ultimately,// set both Idle and Interval to negative values if you want to leave them unchanged.//// Note that Solaris and its derivatives do not support setting Interval to a non-negative value// and Count to a negative value, or vice-versa.typeKeepAliveConfigstruct {// If Enable is true, keep-alive probes are enabled. Enable bool// Idle is the time that the connection must be idle before // the first keep-alive probe is sent. // If zero, a default value of 15 seconds is used. Idle time.Duration// Interval is the time between keep-alive probes. // If zero, a default value of 15 seconds is used. Interval time.Duration// Count is the maximum number of keep-alive probes that // can go unanswered before dropping a connection. // If zero, a default value of 9 is used. Count int}// SyscallConn returns a raw network connection.// This implements the [syscall.Conn] interface.func ( *TCPConn) () (syscall.RawConn, error) {if !.ok() {returnnil, syscall.EINVAL }returnnewRawConn(.fd), nil}// ReadFrom implements the [io.ReaderFrom] ReadFrom method.func ( *TCPConn) ( io.Reader) (int64, error) {if !.ok() {return0, syscall.EINVAL } , := .readFrom()if != nil && != io.EOF { = &OpError{Op: "readfrom", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }return , }// WriteTo implements the io.WriterTo WriteTo method.func ( *TCPConn) ( io.Writer) (int64, error) {if !.ok() {return0, syscall.EINVAL } , := .writeTo()if != nil && != io.EOF { = &OpError{Op: "writeto", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }return , }// CloseRead shuts down the reading side of the TCP connection.// Most callers should just use Close.func ( *TCPConn) () error {if !.ok() {returnsyscall.EINVAL }if := .fd.closeRead(); != nil {return &OpError{Op: "close", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// CloseWrite shuts down the writing side of the TCP connection.// Most callers should just use Close.func ( *TCPConn) () error {if !.ok() {returnsyscall.EINVAL }if := .fd.closeWrite(); != nil {return &OpError{Op: "close", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// SetLinger sets the behavior of Close on a connection which still// has data waiting to be sent or to be acknowledged.//// If sec < 0 (the default), the operating system finishes sending the// data in the background.//// If sec == 0, the operating system discards any unsent or// unacknowledged data.//// If sec > 0, the data is sent in the background as with sec < 0.// On some operating systems including Linux, this may cause Close to block// until all data has been sent or discarded.// On some operating systems after sec seconds have elapsed any remaining// unsent data may be discarded.func ( *TCPConn) ( int) error {if !.ok() {returnsyscall.EINVAL }if := setLinger(.fd, ); != nil {return &OpError{Op: "set", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// SetKeepAlive sets whether the operating system should send// keep-alive messages on the connection.func ( *TCPConn) ( bool) error {if !.ok() {returnsyscall.EINVAL }if := setKeepAlive(.fd, ); != nil {return &OpError{Op: "set", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// SetKeepAlivePeriod sets the duration the connection needs to// remain idle before TCP starts sending keepalive probes.//// Note that calling this method on Windows prior to Windows 10 version 1709// will reset the KeepAliveInterval to the default system value, which is normally 1 second.func ( *TCPConn) ( time.Duration) error {if !.ok() {returnsyscall.EINVAL }if := setKeepAliveIdle(.fd, ); != nil {return &OpError{Op: "set", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// SetNoDelay controls whether the operating system should delay// packet transmission in hopes of sending fewer packets (Nagle's// algorithm). The default is true (no delay), meaning that data is// sent as soon as possible after a Write.func ( *TCPConn) ( bool) error {if !.ok() {returnsyscall.EINVAL }if := setNoDelay(.fd, ); != nil {return &OpError{Op: "set", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }returnnil}// MultipathTCP reports whether the ongoing connection is using MPTCP.//// If Multipath TCP is not supported by the host, by the other peer or// intentionally / accidentally filtered out by a device in between, a// fallback to TCP will be done. This method does its best to check if// MPTCP is still being used or not.//// On Linux, more conditions are verified on kernels >= v5.16, improving// the results.func ( *TCPConn) () (bool, error) {if !.ok() {returnfalse, syscall.EINVAL }returnisUsingMultipathTCP(.fd), nil}func newTCPConn( *netFD, time.Duration, KeepAliveConfig, func(*netFD), func(KeepAliveConfig)) *TCPConn {setNoDelay(, true)if !.Enable && >= 0 { = KeepAliveConfig{Enable: true,Idle: , } } := &TCPConn{conn{}}if .Enable {if != nil { () } .SetKeepAliveConfig()if != nil { () } }return}// DialTCP acts like [Dial] for TCP networks.//// The network must be a TCP network name; see func Dial for details.//// If laddr is nil, a local address is automatically chosen.// If the IP field of raddr is nil or an unspecified IP address, the// local system is assumed.func ( string, , *TCPAddr) (*TCPConn, error) {switch {case"tcp", "tcp4", "tcp6":default:returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: .opAddr(), Err: UnknownNetworkError()} }if == nil {returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: nil, Err: errMissingAddress} } := &sysDialer{network: , address: .String()} , := .dialTCP(context.Background(), , )if != nil {returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: .opAddr(), Err: } }return , nil}// TCPListener is a TCP network listener. Clients should typically// use variables of type [Listener] instead of assuming TCP.typeTCPListenerstruct { fd *netFD lc ListenConfig}// SyscallConn returns a raw network connection.// This implements the [syscall.Conn] interface.//// The returned RawConn only supports calling Control. Read and// Write return an error.func ( *TCPListener) () (syscall.RawConn, error) {if !.ok() {returnnil, syscall.EINVAL }returnnewRawListener(.fd), nil}// AcceptTCP accepts the next incoming call and returns the new// connection.func ( *TCPListener) () (*TCPConn, error) {if !.ok() {returnnil, syscall.EINVAL } , := .accept()if != nil {returnnil, &OpError{Op: "accept", Net: .fd.net, Source: nil, Addr: .fd.laddr, Err: } }return , nil}// Accept implements the Accept method in the [Listener] interface; it// waits for the next call and returns a generic [Conn].func ( *TCPListener) () (Conn, error) {if !.ok() {returnnil, syscall.EINVAL } , := .accept()if != nil {returnnil, &OpError{Op: "accept", Net: .fd.net, Source: nil, Addr: .fd.laddr, Err: } }return , nil}// Close stops listening on the TCP address.// Already Accepted connections are not closed.func ( *TCPListener) () error {if !.ok() {returnsyscall.EINVAL }if := .close(); != nil {return &OpError{Op: "close", Net: .fd.net, Source: nil, Addr: .fd.laddr, Err: } }returnnil}// Addr returns the listener's network address, a [*TCPAddr].// The Addr returned is shared by all invocations of Addr, so// do not modify it.func ( *TCPListener) () Addr { return .fd.laddr }// SetDeadline sets the deadline associated with the listener.// A zero time value disables the deadline.func ( *TCPListener) ( time.Time) error {if !.ok() {returnsyscall.EINVAL }return .fd.SetDeadline()}// File returns a copy of the underlying [os.File].// It is the caller's responsibility to close f when finished.// Closing l does not affect f, and closing f does not affect l.//// The returned os.File's file descriptor is different from the// connection's. Attempting to change properties of the original// using this duplicate may or may not have the desired effect.func ( *TCPListener) () ( *os.File, error) {if !.ok() {returnnil, syscall.EINVAL } , = .file()if != nil {returnnil, &OpError{Op: "file", Net: .fd.net, Source: nil, Addr: .fd.laddr, Err: } }return}// ListenTCP acts like [Listen] for TCP networks.//// The network must be a TCP network name; see func Dial for details.//// If the IP field of laddr is nil or an unspecified IP address,// ListenTCP listens on all available unicast and anycast IP addresses// of the local system.// If the Port field of laddr is 0, a port number is automatically// chosen.func ( string, *TCPAddr) (*TCPListener, error) {switch {case"tcp", "tcp4", "tcp6":default:returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: UnknownNetworkError()} }if == nil { = &TCPAddr{} } := &sysListener{network: , address: .String()} , := .listenTCP(context.Background(), )if != nil {returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: } }return , nil}// roundDurationUp rounds d to the next multiple of to.func roundDurationUp( time.Duration, time.Duration) time.Duration {return ( + - 1) / }
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.