package main
import (
"io"
"log"
"net"
"os"
)
func main() {
conn,err:=net.Dial("tcp","localhost:8000")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout,conn)
}
func mustCopy(dst io.Writer, src io.Reader) {
if _, err := io.Copy(dst, src);err!=nil {
log.Fatal(err)
}
}
讲解
- net.Dial连接一个tcp服务器,并返回一个conn,以下是net.Dial()函数源代码
// Dial connects to the address on the named network.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
// "unixpacket".
//
// For TCP and UDP networks, the address has the form "host:port".
// The host must be a literal IP address, or a host name that can be
// resolved to IP addresses.
// The port must be a literal port number or a service name.
// If the host is a literal IPv6 address it must be enclosed in square
// brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
// The zone specifies the scope of the literal IPv6 address as defined
// in RFC 4007.
// The functions JoinHostPort and SplitHostPort manipulate a pair of
// host and port in this form.
// When using TCP, and the host resolves to multiple IP addresses,
// Dial will try each IP address in order until one succeeds.
//
// Examples:
// Dial("tcp", "golang.org:http")
// Dial("tcp", "192.0.2.1:http")
// Dial("tcp", "198.51.100.1:80")
// Dial("udp", "[2001:db8::1]:domain")
// Dial("udp", "[fe80::1%lo0]:53")
// Dial("tcp", ":80")
//
// For IP networks, the network must be "ip", "ip4" or "ip6" followed
// by a colon and a literal protocol number or a protocol name, and
// the address has the form "host". The host must be a literal IP
// address or a literal IPv6 address with zone.
// It depends on each operating system how the operating system
// behaves with a non-well known protocol number such as "0" or "255".
//
// Examples:
// Dial("ip4:1", "192.0.2.1")
// Dial("ip6:ipv6-icmp", "2001:db8::1")
// Dial("ip6:58", "fe80::1%lo0")
//
// For TCP, UDP and IP networks, if the host is empty or a literal
// unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
// TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
// assumed.
//
// For Unix networks, the address must be a file system path.
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}
两个string参数:network address
返回值类型: Conn error
文档翻译:
Dial是用来连接给定协议名的网络的。如果说listen函数用来创建一个服务器,那么dial函数就是用来连接一个服务器的。连接上之后,给出一个Conn接口类型的变量 。
这里我有一些不懂的地方。
mustCopy传入的第二个参数是conn,但是函数中的类型是io.Reader。可是conn的类型是以Conn为接口名的接口。具体看来呢.io.reader接口实现了函数
Read(p []byte) (n int, err error)
而Conn实现了函数:
Read(b []byte) (n int, err error)
这本权威的书给出了一个关于接口的知识点。如果两个接口同时实现了同一个函数,那么我们可以将范围大的接口类型作为实参,范围小的接口类型作为形参来书写函数呢。
就我目前的知识储备来看呢,这里算是一个坑。将来的某个时间点我会回来填上这个坑的。
有疑问加站长微信联系(非本文作者)