func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
switch network {
case "tcp", "tcp4", "tcp6":
default:
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
}
if raddr == nil {
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
}
c, err := dialTCP(context.Background(), network, laddr, raddr)
if err != nil {
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
}
return c, nil
}
DialTCP()函数接收三个参数:
network: 这个参数和ResolveTCPAddr的network参数一样,必须是TCP网络名。 laddr: TCPAddr类型的指针, 代表本地TCP地址。 raddr: TCPAddr类型的指针,代表的是远程TCP地址。它会连接拨号两个TCP地址,并返回这个连接作为net.TCPConn对象返回(连接失败返回error)。如果我们不需要对Dial设置有过多控制,那么我们就可以使用Dial()代替。
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}
Dial()函数接收一个TCP地址,返回一个一般的net.Conn。 这已经足够我们的测试用例了。然而如果你需要只有在TCP连接上的可用功能,可以使用TCP变体(DialTCP, TCPConn, TCPAddr等等)。
成功拨号之后,我们就可以如上所述的那样,将新的连接与其他的输入输出流同等对待了。我们甚至可以将连接包装进bufio.ReadWriter中,这样可以使用各种ReadWriter方法,例如ReadString(), ReadBytes, WriteString等等。
func Open(addr string) (*bufio.ReadWriter, error) {
conn, err := net.Dial("tcp", addr)
if err != nil {
return nil, errors.Wrap(err, "Dialing "+addr+" failed")
}
// 将net.Conn对象包装到bufio.ReadWriter中
return bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)), nil
}
记住缓冲Writer在写之后需要调用Flush()方法, 这样所有的数据才会刷到底层网络连接中。
最后,每个连接对象都有一个Close()方法来终止通信。
微调(fine tuning)
Dialer结构体定义如下:
type Dialer struct {
Timeout time.Duration
Deadline time.Time
LocalAddr Addr
DualStack bool
FallbackDelay time.Duration
KeepAlive time.Duration
Resolver *Resolver
Cancel <-chan struct{}
}
Timeout: 拨号等待连接结束的最大时间数。如果同时设置了Deadline, 可以更早失败。默认没有超时。 当使用TCP并使用多个IP地址拨号主机名,超时会在它们之间划分。使用或不使用超时,操作系统都可以强迫更早超时。例如,TCP超时一般在3分钟左右。
Deadline: 是拨号即将失败的绝对时间点。如果设置了Timeout, 可能会更早失败。0值表示没有截止期限, 或者依赖操作系统或使用Timeout选项。
LocalAddr: 是拨号一个地址时使用的本地地址。这个地址必须是要拨号的network地址完全兼容的类型。如果为nil, 会自动选择一个本地地址。
DualStack: 这个属性可以启用RFC 6555兼容的"欢乐眼球(Happy Eyeballs) "拨号,当network是tcp时,address参数中的host可以被解析被IPv4和IPv6地址。这样就允许客户端容忍(tolerate)一个地址家族的网络规定稍微打破一下。
FallbackDelay: 当DualStack启用的时候, 指定在产生回退连接之前需要等待的时间。如果设置为0, 默认使用延时300ms。
KeepAlive: 为活动网络连接指定保持活动的时间。如果设置为0,没有启用keep-alive。不支持keep-alive的网络协议会忽略掉这个字段。
Resolver: 可选项,指定使用的可替代resolver。
Cancel: 可选通道,它的闭包表示拨号应该被取消。不是所有的拨号类型都支持拨号取消。 已废弃,可使用DialContext代替。









