Golang goroutine和chan 教程05: 实现一个nc netcat

我加入简书的路程 · · 1006 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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)
    }
}

讲解

  1. 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)

这本权威的书给出了一个关于接口的知识点。如果两个接口同时实现了同一个函数,那么我们可以将范围大的接口类型作为实参,范围小的接口类型作为形参来书写函数呢。
就我目前的知识储备来看呢,这里算是一个坑。将来的某个时间点我会回来填上这个坑的。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:我加入简书的路程

查看原文:Golang goroutine和chan 教程05: 实现一个nc netcat

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1006 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传