net包对于网络I/O提供了便携式接口,包括TCP/IP,UDP,域名解析以及Unix Socket。尽管net包提供了大量访问底层的接口,但是大多数情况下,客户端仅仅只需要最基本的接口,例如Dial,LIsten,Accepte以及分配的conn连接和listener接口。 crypto/tls包使用相同的接口以及类似的Dial和Listen函数。下面对net包进行具体分析。
首先介绍其中常量:
- const (
- IPv4len = 4
- IPv6len = 16
- )
很容易看出这表示ip地址的长度(bytes),其中ipv4长度是4,ipv6地址长度是16
变量:
常用的ipv4地址:
- var (
- IPv4bcast = IPv4(255,255,255) // 广播地址
- IPv4allsys = IPv4(224,1) // 所有系统,包括主机和路由器,这是一个组播地址
- IPv4allrouter = IPv4(224,2) // 所有组播路由器
- IPv4zero = IPv4(0,0) // 本地网络,只能作为本地源地址其才是合法的
- )
常用的IPV6地址:
- var (
- IPv6zero = IP{0,0}
- IPv6unspecified = IP{0,0}
- IPv6loopback = IP{0,1}
- IPv6interfacelocalallnodes = IP{0xff,0x01,0x01}
- IPv6linklocalallnodes = IP{0xff,0x02,0x01}
- IPv6linklocalallrouters = IP{0xff,0x02}
- )
接下来讲一下IPV4和IPV6相关知识,了解的请直接跳过。
IP地址(Internet Protocol Address,称为互联网协议地址,简写为IP Address),是一种给主机在Internet上进行编址的方式。常见的IP地址,分为IPV4和IPV6地址两类。
IPV4是由32位二进制数表示,其表示为XXX.XXX.XXX.XXX,每组XXX代表小于或等于255的10进制数,IPV4地址总数为232,不过,一些地址是为特殊用途所保留的,如专用网络(约18百万个地址)和多播地址(约270百万个地址)。其中IPV4分为ABCDE五类地址,分别进行介绍:
A类地址 第一位为0,注意是位 1、第1字节为网络地址,其它3个字节为主机地址
2、地址范围:1.0.0.1—126.255.255.254
3、10.X.X.X是私有地址,范围从10.0.0.0-10.255.255.255
4、127.X.X.X是保留地址,用做环回测试。
B类地址 前两位为10,注意是位 1、 第1字节和第2字节为网络地址,后2个字节为主机地址
2、地址范围:128.0.0.1—191.255.255.254
3、私有地址范围:172.16.0.0—172.31.255.255
4、保留地址:169.254.X.X
C类地址 前三位为110,注意是位 1、前三个字节为网络地址,最后字节为主机地址
2、地址范围:192.0.0.1—223.255.255.254
3、私有地址:192.168.X.X,范围从192.168.0.0-192.168.255.255
D类地址 前四位为1110,注意三位 1、不分网络地址和主机地址。
2、地址范围:224.0.0.1—239.255.255.254
E类地址 前五位为11110,注意四位 1、不分网络地址和主机地址
2、地址范围:240.0.0.1—255.255.255.254
此外还有几个特殊IP地址:
1、0.0.0.0只能做源地址
2、255.255.255.255是广播地址
3、127.x.x.x为环回地址,本机使用
4、专用地址:
10/8 地址范围:10.0.0.0——10.255.255.255,
172.16/12 地址范围:172.16.0.0——172.31.255.255,
192.168/16地址范围:192.168.0.0——192.168.255.255。
224.0.0.1
组播地址,注意它和广播的区别。从224.0.0.0到239.255.255.255都是这样的地址。224.0.0.1特指所有主机和路由器,224.0.0.2特指所有 路由器。这样的地址多用于一些特定的程序以及多媒体程序。如果你的主机开启了IRDP(Internet路由发现,使用组播功能)功能,那么你的主机路由表中应该有这样一条路由。
169.254.x.x
如果你的主机使用了DHCP功能自动获得一个IP地址,那么当你的DHCP服务器发生故障,或响应时间太长而超出了一个 系统规定的时间,Wingdows系统会为你分配这样一个地址。如果你发现你的主机IP地址是一个诸如此类的地址,很不幸,十有八九是你的网络不能正常运行了。
至于单播广播和组播介绍及优缺点,请看这篇文章:http://www.h3c.com.cn/products___technology/technology/group_management/other_technology/technology_recommend/200805/605846_30003_0.htm
由于IPV4地址共有232个地址,约为43亿,导致其不够使用,从而诞生了IPV6,IPV6地址长度为128位,其地址总数为2128个,IPV6解决了IPV4地址不够用的问题,IPV6更加详细介绍请参考http://zh.wikipedia.org/wiki/IPv6
func InterfaceAddrs() ([]Addr,error) //InterfaceAddrs返回该系统的网络接口的地址列表。
func Interfaces() ([]Interface,error) //Interfaces返回该系统的网络接口列表。
func JoinHostPort(host,port string) string //JoinHostPort将host和port合并为一个网络地址。一般格式为"host:port";如果host含有冒号或百分号,格式为"[host]:port"。
func LookupAddr(addr string) (name []string,err error) //对于给定的地址进行反向查找,并返回映射到那个地址的一个list列表
func LookupCNAME(name string) (cname string,err error) //返回给定名字的规范的DNS主机名称,如果调用者不关心这个name是否规范,可以直接调用LookupHost 或者 LookupIP,这两个函数都会在查询时考虑到name的规范性。
func LookupHost(host string) (addrs []string,err error) //通过利用本地解析器对给定的host进行查找,返回主机地址的数组
func LookupIP(host string) (addrs []IP,err error) //通过利用本地解析器查找host,返回主机ipv4和ipv6地址的一个数组
举例说明其用法:
- package main
- import (
- "fmt"
- "net"
- )
- func main() {
- addr,_ := net.InterfaceAddrs()
- fmt.Println(addr) //[127.0.0.1/8 10.236.15.24/24 ::1/128 fe80::3617:ebff:febe:f123/64],本地地址,ipv4和ipv6地址,这些信息可通过ifconfig命令看到
- interfaces,_ := net.Interfaces()
- fmt.Println(interfaces) //[{1 65536 lo up|loopback} {2 1500 eth0 34:17:eb:be:f1:23 up|broadcast|multicast}] 类型:MTU(最大传输单元),网络接口名,支持状态
- hp := net.JoinHostPort("127.0.0.1","8080")
- fmt.Println(hp) //127.0.0.1:8080,根据ip和端口组成一个addr字符串表示
- lt,_ := net.LookupAddr("127.0.0.1")
- fmt.Println(lt) //[localhost],根据地址查找到改地址的一个映射列表
- cname,_ := net.LookupCNAME("www.baidu.com")
- fmt.Println(cname) //www.a.shifen.com,查找规范的dns主机名字
- host,_ := net.LookupHost("www.baidu.com")
- fmt.Println(host) //[111.13.100.92 111.13.100.91],查找给定域名的host名称
- ip,_ := net.LookupIP("www.baidu.com")
- fmt.Println(ip) //[111.13.100.92 111.13.100.91],查找给定域名的ip地址,可通过nslookup www.baidu.com进行查找操作.
- }
在讲解下面函数用法之前,先说明几个名词含义(参考如下连接:http://blog.sina.com.cn/s/blog_7ff492150101kqbh.html):
域名解析记录A、CNAME、MX、NS、TXT、AAAA、SRV、显性URL、隐形URL含义
1. A记录(IP指向):把域名(www.xxx.com)解析到某一个指定IP。用户可以将该域名解析到自己的web server上,同时也可以设置该域名的二级域名。
2. CNAME记录(Canonical Name 别名指向):相当于用子域名代替IP地址。(优点:如果IP地址改变,只需要更改子域名的解析即可。)
3. MX记录:指向一个邮件服务器,用于电子邮件系统发邮件时根据收信人的地址后缀来定位邮件服务器。
4. NS记录:1. 解析服务器记录。用来表明由哪台服务器对该域名进行解析,这里的NS记录只对子域名生效。例如用户希望由15.54.66.88这台服务器解析coco.mydomain.com,则需要设置coco.mydomain.com的NS记录。
说明:
·“优先级”中的数字越小表示级别越高;
·“IP地址/主机名”中既可以填写IP地址,也可以填写像ns.mydomain.com这样的主机地址,但必须保证该主机地址有效。如,将coco.mydomain.com的NS记录指向到ns.mydomain.com,在设置NS记录的同时还需要设置ns.mydomain.com的指向,否则NS记录将无法正常解析;
·优先级:NS记录优先于A记录。即,如果一个主机地址同时存在NS记录和A记录,则A记录不生效。这里的NS记录只对子域名生效。
5. TXT记录:为某个主机名或域名设置联系信息,如:
admin IN TXT "管理员,电话: 13901234567"
mail IN TXT "邮件主机,存放在xxx,管理人:AAA"
Jim IN TXT "contact: abc@mailserver.com"
也就是您可以设置 TXT ,以便使别人联系到您。
6. AAAA记录1. (AAAA record):是用来将域名解析到IPv6地址的DNS记录。用户可以将一个域名解析到IPv6地址上,也可以将子域名解析到IPv6地址上。(设置AAAA记录:
i. 主机记录处填子域名。若添加泛解析,则填写*。若将主域名直接进行解析,则留空或填写@。
ii. 记录类型为AAAA。记录值为ip地址,只可以填写IPv6地址(比如::1)。
iii. MX优先级不需要填写。
iv. TTL添加时系统会自动生成,默认为600秒。)
7. SRV记录:一般是为Microsoft的活动目录设置时的应用。DNS可以独立于活动目录,但是活动目录必须有DNS的帮助才能工作。为了活动目录能够正常的工作,DNS服务器必须支持服务定位(SRV)资源记录,资源记录把服务名字映射为提供服务的服务器名字。活动目录客户和域控制器使用SRV资源记录决定域控制器的IP地址。
此技术细节请参考相应网站(看过的见论坛帖http://bbs.28tui.com/forum.PHP?mod=viewthread&tid=2321129)
8. 显性URL记录:访问域名时,会自动跳转到所指的另一个网络地址(URL),此时在浏览器地址栏中显示的是跳转的地址。
9. 隐形URL记录:访问域名时,会自动跳转到所指的另一个网络地址(URL),此时在浏览器地址栏中显示的是原域名地址。
func LookupMX(name string) (mx []*MX,err error) //查找指定域名的DNS MX邮件交换记录,并按照优先顺序进行返回。
func LookupNS(name string) (ns []*NS,err error) //返回指定域名的DNS NS记录
func LookupPort(network,service string) (port int,err error) //返回指定network和service的端口
func LookupSRV(service,proto,name string) (cname string,addrs []*SRV,err error) //对指定的service服务,protocol协议以及name域名进行srv查询,其中proto协议表示tcp或者udp,返回的record记录按照优先级进行排序,同一优先级下的按照weight权重进行随机排序。LookupSRV函数按照RFC 2782标准来构建用于查询的DNS。也就是说,它查询_service._proto.name。当service和proto参数都是空字符串时,LookupSRV将会直接查找name。
func LookupTXT(name string) (txt []string,err error) //查找指定域名的DNS TXT记录
func SplitHostPort(hostport string) (host,port string,err error) //SplitHostPort将如下形式的网络地址拆分成host和port形式,其中拆分前的格式如下:"host:port","[host]:port" or "[ipv6-host%zone]:port",其中ipv6的地址或者主机名必须用方括号括起来,如"[::1]:80"、"[ipv6-host]:http"、"[ipv6-host%zone]:80"
接下来讲述一下net包中存在的error:
type Error //表示网络错误
- type Error interface {
- error //错误
- Timeout() bool // Is the error a timeout? 该错误是时间超时错误吗?
- Temporary() bool // Is the error temporary? 这个错误是一个临时错误吗?
- }
任何实现了error接口中方法的结构体都实现了网络error
其主要有以下集中错误:
type AddrError //网络地址错误
- type AddrError struct {
- Err string //错误
- Addr string //地址字符串表示
- }
func (e *AddrError) Error() string //错误
func (e *AddrError) Temporary() bool //该错误是否是一个临时错误
func (e *AddrError) Timeout() bool //该错误是否是超时错误
type DNSConfigError //DNS配置错误,表示在读取机器DNS配置过程中出现的错误
- type DNSConfigError struct {
- Err error
- }
func (e *DNSConfigError) Error() string
func (e *DNSConfigError) Temporary() bool
func (e *DNSConfigError) Timeout() bool
type DNSError //DNS错误,表示DNS查询错误
- type DNSError struct {
- Err string // description of the error,错误描述
- Name string // name looked for,查询 名称
- Server string // server used,服务
- IsTimeout bool,是否超时
- }
func (e *DNSError) Error() string
func (e *DNSError) Temporary() bool
func (e *DNSError) Timeout() bool
以DNSError为例,举例说明net保重Error的用法
- package main
- import (
- "fmt"
- "net"
- )
- func main() {
- dnserror := net.DNSError{
- Err: "dns error",Name: "dnserr",Server: "dns search",IsTimeout: true,}
- fmt.Println(dnserror.Error()) //lookup dnserr on dns search: dns error
- fmt.Println(dnserror.Temporary()) //true
- fmt.Println(dnserror.Timeout()) //true
- fmt.Println(dnserror.Server) //dns search
- fmt.Println(dnserror.Err) //dns error
- fmt.Println(dnserror.Name) //dnserr
- fmt.Println(dnserror.IsTimeout) //true
- }
type InvalidAddrError //无效地址错误
- type InvalidAddrError string
func (e InvalidAddrError) Error() string
func (e InvalidAddrError) Temporary() bool
func (e InvalidAddrError) Timeout() bool
type OpError //操作错误,OpError是在net包中经常背用刀的一个函数,它描述一个错误的操作,网络类型以及地址。
- type OpError struct {
- Op string //Op是引起错误的操作,如"read"或"write"
- Net string //Net表示错误出现的网络类型,如tcp或者udp6
- Addr Addr //Addr表示错误出现的网络抵制
- Err error //Err表示错误
- }
func (e *OpError) Error() string
func (e *OpError) Temporary() bool
func (e *OpError) Timeout() bool
- var (
- ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
- )
type ParseError //解析错误,ParseError表示一个格式错误的字符串,其中Type表示期望的格式。
- type ParseError struct {
- Type string
- Text string
- }
func (e *ParseError) Error() string //将错误表示为字符串形式
type UnkNownNetworkError //未知网络错误
- type UnkNownNetworkError string
func (e UnkNownNetworkError) Error() string
func (e UnkNownNetworkError) Temporary() bool
func (e UnkNownNetworkError) Timeout() bool
type Addr //网络终端地址
- type Addr interface {
- Network() string // 网络名称
- String() string // 地址字符串表示
- }
type Conn //conn是一个通用的面向流的网络连接,多个goroutine可以同时调用conn中的方法。
- type Conn interface {
- // Read从连接中读取数据,Read方法会在超过某个固定时间限制后返回一个表示超时的错误,该错误的TImeout()==True
- Read(b []byte) (n int,err error)
- // Write向conn中写入数据,与Read类似, Write方法也会在超过某个固定时间后返回超时错误,该错误的Timeout()==True
- Write(b []byte) (n int,err error)
- // Close方法关闭该连接,同时任何阻塞的Read或Write方法将不再阻塞,并且返回错误。
- Close() error
- // 返回本地网络地址
- LocalAddr() Addr
- // 返回远端网络地址
- RemoteAddr() Addr
- // 设定连接的读写deadline,它等价于调用SetReadDeadline和SetWriteDeadline进行conn连接的读写deadline设定。其中deadline是一个绝对时间,
- //在deadline时间之后,任何的读写操作都不再阻塞,而是直接失败,deadline对之后的所有I/O操作都起效,而不仅仅是下一次的读或写操作,
- // :一:空闲超时,这种方法实现其中有两类超时比较特殊是在每次成功读或者写操作后都延长超时期限,当没有读写操作空闲时便会超时;二:参数t为零值表示不设置
- //超时期限,即不会超时timeout
- SetDeadline(t time.Time) error
- // 设定连接的读操作deadline,参数t为零值表示不设置期限
- SetReadDeadline(t time.Time) error
- // 设定连接的写操作deadline,参数t为零值表示不设置期限
- // 即使写超时,也有可能出现写入字数n>0,说明成功写入了部分数据,但是没有将数据全部写入。
- SetWriteDeadline(t time.Time) error
- }
func Dial(network,address string) (Conn,error) //Dial 连接到指定address和name的网络,其中network包含如下几种:"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". 对于TCP和UDP网络来说,addresses的形式如下host:port,其行使和JoinHostPort以及SplitHostPort函数中的addresses形式一致。举例如下所示:
- Dial("tcp","12.34.56.78:80")
- Dial("tcp","google.com:http")
- Dial("tcp","[2001:db8::1]:http")
- Dial("tcp","[fe80::1%lo0]:80")
对于IP网络,network必须是ip,ipv4或者ipv6,并且他们后面必须跟着冒号和协议数字协议名字,并且这个地址必须是一个ip地址,举例如下:
- Dial("ip4:1","127.0.0.1")
- Dial("ip6:ospf","::1")
对于Unix网络来说,address必须是一个文件系统的路径。
func DialTimeout(network,address string,timeout time.Duration) (Conn,error) //该函数与Dial函数类似,但是多一个超时设置timeout,如果需要的话,timeout中包含域名解析
func FileConn(f *os.File) (c Conn,err error) //FileConn返回一个对文件f的网络连接的复制copy,当调用完毕后,用户需要自己关闭文件f,由于是复制关系,所以关闭c和关闭f二者互不影响。
func Pipe() (Conn,Conn) //Pipe在内存中创建一个同步全双工的网络连接。连接的两端都实现了Conn接口。一端的读取对应另一端的写入,在这个过程中复制数据是直接在两端之间进行复制,而没有内部缓存。
type Dialer //包含连接到一个地址的选项,//在Dialer结构体中的每个参数的零值相当于没有那个值,因此调用零值的Dialer中的Dial函数相当于直接调用Dial函数
- type Dialer struct {
- // Timeout是dial操作等待连接建立的最大时长,默认值代表没有超时。如果Deadline字段也被设置了,dial操作也可能更早失败。
- // 不管有没有设置超时,操作系统都可能强制执行它的超时设置。例如,TCP(系统)超时一般在3分钟左右。Timeout是一个相对时间,是时间段,而Deadline是一个绝
- //对时间,是时间点,这是二者的区别
- Timeout time.Duration
- // Deadline是一个具体的时间点期限,超过该期限后,dial操作就会失败。如果Timeout字段也被设置了,dial操作也可能更早失败。零值表示没有期限。
- Deadline time.Time
- // LocalAddr是dial一个地址时使用的本地地址。
- // 该地址必须是与dial的网络相容的类型。
- // 如果为nil,将会自动选择一个本地地址。
- LocalAddr Addr
- // 当网络类型是tcp并且一个主机名字具有多个dns记录地址时,DualStack允许一个dial创建多个ipv4和ipv6的连接,并且返回第一个创建的连接
- DualStack bool
- // KeepAlive指定一个网络连接的保持声明的时间段;如果为0,会禁止keep-alive。当网络协议不支持keep-alives时便会忽略掉这个值。
- // 不支持keep-alive的网络连接会忽略本字段。
- KeepAlive time.Duration
- }
func (d *Dialer) Dial(network,error) //Dial在指定的网络上连接指定的地址。详细用法参见Dial函数获取网络和地址参数的描述
type Flags
- type Flags uint
- const (
- FlagUp Flags = 1 << iota // 接口处于互动状态
- FlagBroadcast // 接口支持广播
- FlagLoopback // 接口是回环接口
- FlagPointToPoint // 接口属于点到点
- FlagMulticast // 接口支持组播
- )
func (f Flags) String() string //将f用字符串表示
type HardwareAddr //硬件地址,HardwareAddr表示一个物理硬件地址
- type HardwareAddr []byte
func ParseMAC(s string) (hw HardwareAddr,err error) //将字符串解析成硬件物理地址,其中ParseMAC函数使用如下格式解析一个IEEE 802 MAC-48、EUI-48或EUI-64硬件地址:
- 01:23:45:67:89:ab
- 01:23:45:67:89:ab:cd:ef
- 01-23-45-67-89-ab
- 01-23-45-67-89-ab-cd-ef
- 0123.4567.89ab
- 0123.4567.89ab.cdef
func (a HardwareAddr) String() string //硬件地址的字符串表示
type Interface //Interface表示一个在网络接口名和索引之间的映射,他也包含网络借口设备信息。
- type Interface struct {
- Index int // 索引,必须为正整数
- MTU int // 最大传输单元
- Name string // 名字,例如: "en0","lo0","eth0.100"
- HardwareAddr HardwareAddr //硬件地址,例如: IEEE MAC-48,EUI-48 and EUI-64 form
- Flags Flags // flags标记,例如: FlagUp,FlagLoopback,FlagMulticast
- }
func InterfaceByIndex(index int) (*Interface,error) //通过指定的索引index返回相应的接口
func InterfaceByName(name string) (*Interface,error) //通过指定的名字Name返回相应的接口
func (ifi *Interface) Addrs() ([]Addr,error) //返回指定接口的address
func (ifi *Interface) MulticastAddrs() ([]Addr,error) //MulticastAddrs返回网络接口ifi加入的多播组地址。
type Listener //Listener是一个用于面向流的网络协议的公用的网络监听器接口。多个线程可能会同时调用一个Listener的方法。
- type Listener interface {
- Accept() (c Conn,err error)//等待并返回下一个连接到该连接的连接
- Close() error //关闭listener,关闭后,任何阻塞accept的操作都不再阻塞,并且返回error
- Addr() Addr //返回该接口的网络地址
- }
func FileListener(f *os.File) (l Listener,err error) //返回对于文件f的网络listener的复制。
func Listen(net,laddr string) (Listener,error) //返回在一个本地网络地址laddr上监听的Listener。网络类型参数net必须是面向流的网络:"tcp"、"tcp4"、"tcp6"、"unix"或"unixpacket"。具体参见Dial函数获取laddr的语法。
type PacketConn
func FilePacketConn(f *os.File) (c PacketConn,err error)
func ListenPacket(net,laddr string) (PacketConn,error)
type MX //MX代表一条DNS MX记录(邮件交换记录),根据收信人的地址后缀来定位邮件服务器。
- type MX struct {
- Host string
- Pref uint16
- }
type NS //NS代表一条DNS NS记录(域名服务器记录),指定该域名由哪个DNS服务器来进行解析。
- type NS struct {
- Host string
- }
type SRV //SRV代表一条DNS SRV记录(资源记录),记录某个服务由哪台计算机提供。
- type SRV struct {
- Target string
- Port uint16
- Priority uint16
- Weight uint16
- }
IP地址(Internet Protocol Address,称为互联网协议地址,简写为IP Address),是一种给主机在Internet上进行编址的方式。
type IP //IP表示一个简单的IP地址,它是一个byte类型的slice,能够接受4字节(IPV4)或者16字节(IPV6)输入。注意,IP地址是IPv4地址还是IPv6地址是语义上的特性,而不取决于切片的长度:16字节的切片也可以是IPv4地址。
- type IP []byte
func IPv4(a,b,c,d byte) IP //ipv4返回一个ipv4地址格式(a.b.c.d)的地址,这是16-byte的
func ParseCIDR(s string) (IP,*IPNet,error) //ParseCIDR将字符串s解析成一个ip地址和子网掩码的结构体中,其中字符串格式必须是IP地址和子网掩码的字符串,如:"192.168.100.1/24"或"2001:DB8::/48“等。
func ParseIP(s string) IP //ParseIP将s解析为IP地址,并返回该地址。如果s不是合法的IP地址表示,则ParseIP会返回nil。字符串可以是小数点分隔的IPv4格式(如"74.125.19.99")或IPv6格式(如"2001:4860:0:2001::68")格式。
func (ip IP) DefaultMask() IPMask //返回IP的默认子网掩码,只有ipv4具有默认子网掩码,如果ip不是一个有效的ipv4地址,则默认子网掩码返回nil
func (ip IP) Equal(x IP) bool //判断两个ip地址是否相等,其中一个ipv4地址以及相同具有ipv6格式的相同的地址认为是相等的,返回true
func (ip IP) IsGlobalUnicast() bool //判断是否是全局单播地址
func (ip IP) IsInterfaceLocalMulticast() bool //判断是不是本地组播地址
func (ip IP) IsLinkLocalMulticast() bool //判断是否是链路本地组播地址
func (ip IP) IsLinkLocalUnicast() bool //判断是否时链路本地单播地址
func (ip IP) IsLoopback() bool //判断是否是回环地址
func (ip IP) IsMulticast() bool //判断是否是组播地址
func (ip IP) IsUnspecified() bool //判断是否是未指定地址
func (ip IP) MarshalText() ([]byte,error)//实现了encoding.TextMarshaler的接口,其编码方式同String()函数的返回值一样。
func (ip IP) Mask(mask IPMask) IP //将mask作为ip的子网掩码获取其IP地址
func (ip IP) String() string //获取ip地址的字符串表示,如果ip是IPv4地址,返回值的格式为点分隔的,如"74.125.19.99";否则表示为IPv6格式,如"2001:4860:0:2001::68"。
func (ip IP) To16() IP //将一个 IP地址转换为16字节表示。如果ip不是一个IP地址(长度错误),To16会返回nil。 To16可对ip地址进行转换,包括IPV4和IPV6,而To4只能对IPV4地址进行转换,这就是To16和To4的区别。
func (ip IP) To4() IP //将一个 IPV4地址转换为4字节表示,如果ip不是一个ipv4地址,则返回nil
func (ip *IP) UnmarshalText(text []byte) error //将ip进行反序列化,其实现了encoding.TextUnmarshaler的接口,IP地址字符串应该是ParseIP函数可以接受的格式。
type IPAddr //表示一个IP终端的地址
- type IPAddr struct {
- IP IP
- Zone string // IPv6 寻址范围
- }
func ResolveIPAddr(net,addr string) (*IPAddr,error) //将ip地址解析成形如"host"或者"ipv6-host%zone"的地址形式,解析域名必须在指定的网络中,指定网络包括ip,ip4或者ip6
func (a *IPAddr) Network() string //返回地址的网络类型"ip"
func (a *IPAddr) String() string
type IPConn //IPConn类型代表IP网络连接,实现了Conn和PacketConn接口
func DialIP(netProto string,laddr,raddr *IPAddr) (*IPConn,error)//DialIP在网络协议netProto上连接本地地址laddr和远端地址raddr,netProto必须是"ip"、"ip4"或"ip6"后跟冒号和协议名或协议号。
func ListenIP(netProto string,laddr *IPAddr) (*IPConn,error)//监听传输到本地ip地址的数据包,返回的ReadFrom和WriteTo方法能够用来发送和接受IP数据包
func (c *IPConn) Close() error//关闭连接
func (c *IPConn) File() (f *os.File,err error)//File设定底层的os.File为阻塞模式并返回一个copy副本,当结束时,调用者需要关闭文件,其中原文件和副本之间相互不影响,返回的os.file的文件描述符与网络连接中的文件是不同的,使用该副本修改本体的属性可能会也可能不会得到期望的效果.
func (c *IPConn) LocalAddr() Addr //返回本地的网络地址
func (c *IPConn) Read(b []byte) (int,error) //实现conn接口的读方法,将数据读入b中
func (c *IPConn) ReadFrom(b []byte) (int,Addr,error)//实现了conn的readfrom方法
func (c *IPConn) ReadFromIP(b []byte) (int,*IPAddr,error)//从c中读取一个ip包,将有效信息拷贝到b,返回拷贝的字节数和数据包的来源地址.可以通过timeout()使得该函数超时并且返回一个错误.
func (c *IPConn) ReadMsgIP(b,oob []byte) (n,oobn,flags int,addr *IPAddr,err error)//从c中读取一个ip包,将有效数据拷贝b,相关的额外信息拷贝进oob,返回拷贝进b和oob的字节数,数据包的flag,数据包来源地址以及可能出现的错误.
func (c *IPConn) RemoteAddr() Addr //返回远端网络地址
func (c *IPConn) SetDeadline(t time.Time) error//设定读写操作的绝对过期时间,是一个时间点
func (c *IPConn) SetReadBuffer(bytes int) error//设定该连接的接受缓存的大小
func (c *IPConn) SetReadDeadline(t time.Time) error//设定读操作的绝对过期时间
func (c *IPConn) SetWriteBuffer(bytes int) error//设定该连接的发送缓存大小
func (c *IPConn) SetWriteDeadline(t time.Time) error//设定写操作的绝对过期时间
func (c *IPConn) Write(b []byte) (int,error)//将b中数据写入c中,并返回写入的字节数
func (c *IPConn) WriteMsgIP(b,oob []byte,addr *IPAddr) (n,oobn int,err error)//将b和oob中的有效信息写入c中的地址,返回写入的字节数目
func (c *IPConn) WriteTo(b []byte,addr Addr) (int,error)//WriteTo实现PacketConn接口WriteTo方法
func (c *IPConn) WriteToIP(b []byte,addr *IPAddr) (int,error)//通过c向add写一个ip包,并从b中复制有效信息.可以通过设定timeout值使其过期.
type IPMask //IpMask代表一个ip地址
- type IPMask []byte
func CIDRMask(ones,bits int) IPMask //返回一个CIDRMask,其中CIDRMask总bit数目是bits,钱ones位是1,其余位是0.
func IPv4Mask(a,d byte) IPMask//返回ip掩码,其中ip掩码形式是ipv4掩码(4 byte模式)a.b.c.d
func (m IPMask) Size() (ones,bits int)//返回掩码的前面1的数目以及总数目,如果m不是规范的子网掩码(前面为1后面为0),则返回0,0
func (m IPMask) String() string//返回掩码m的16机制表示,没有标点符号
type IPNet //表示一个ip网络
- type IPNet struct {
- IP IP //网络地址
- Mask IPMask // 子网掩码
- }
func (n *IPNet) Contains(ip IP) bool//判定是否n中包含ip
func (n *IPNet) Network() string//返回地址的网络名,形式是ip+net
func (n *IPNet) String() string//返回ipnet n的cidr模式,形如RFC 4632 和RFC 4291中定义的 "192.168.100.1/24"or "2001:DB8::/48",如果掩码不是规范模式,将会返回一个如下形式的字符串:ip地址/一个由16进制字符组成不含标点的一个字符串,例如"192.168.100.1/c000ff00".
type TCPAddr //表示TCP终端地址
- type TCPAddr struct {
- IP IP
- Port int
- Zone string // IPv6寻址范围
- }
func ResolveTCPAddr(net,addr string) (*TCPAddr,error)//将一个地址解析成TCP地址形式,形如"host:port"或 "[ipv6-host%zone]:port",解析得到网络域名和端口名.其中net必须是"tcp","tcp4"或者"tcp6",IPv6地址字面值/名称必须用方括号包起来,如"[::1]:80"、"[ipv6-host]:http"或"[ipv6-host%zone]:80".
func (a *TCPAddr) Network() string //返回地址的网络类型,"tcp"
func (a *TCPAddr) String() string
type TCPConn//TCPConn是TCP网络连接,其实现了Conn接口,其中方法大部分与IPConn相同,这里不再赘述.
func DialTCP(net string,laddr,raddr *TCPAddr) (*TCPConn,error)
func (c *TCPConn) Close() error
func (c *TCPConn) CloseRead() error
func (c *TCPConn) CloseWrite() error
func (c *TCPConn) File() (f *os.File,err error)
func (c *TCPConn) LocalAddr() Addr
func (c *TCPConn) Read(b []byte) (int,error)
func (c *TCPConn) ReadFrom(r io.Reader) (int64,error)
func (c *TCPConn) RemoteAddr() Addr
func (c *TCPConn) SetDeadline(t time.Time) error
func (c *TCPConn) SetKeepAlive(keepalive bool) error //设置操作系统是否应该在该连接中发送keepalive信息
func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error //设定keepalive的生存周期
func (c *TCPConn) SetLinger(sec int) error //SetLinger设定一个连接的关闭行为当该连接中仍有数据等待发送或者确认.如果sec<0(默认形式),操作系统将在后台完成发送数据操作;如果sec==0,操作系统将任何未发送或者未确认的数据丢弃;当sec>0,数据将在后台进行发送,这点和sec<0时效果一致.然而,在一些操作系统中,当sec秒之后,系统将任何未发送的数据丢弃.
func (c *TCPConn) SetNoDelay(noDelay bool) error//控制是否操作系统为了发送更少的数据包(Nagle's算法)而延迟数据包的发送,默认值是true(不延迟),这意味着数据将在写后尽可能快的进行发送,而不是延迟发送.
func (c *TCPConn) SetReadBuffer(bytes int) error //设定操作系统对于conn连接接受缓存的大小
func (c *TCPConn) SetReadDeadline(t time.Time) error//设定读超时时间
func (c *TCPConn) SetWriteBuffer(bytes int) error//设定操作系统对于conn连接发送缓存的大小
func (c *TCPConn) SetWriteDeadline(t time.Time) error//设定发送超时时间
func (c *TCPConn) Write(b []byte) (int,error)//实现了write接口方法
type TCPListener//TCP监听器,客户端应该使用不同类型的监听,而不是默认的TCP
func ListenTCP(net string,laddr *TCPAddr) (*TCPListener,error)//声明Tcp地址laddr并且返回一个tcp listener,其中net必须是tcp,tcp4或者tcp6,如果laddr端口是0,则ListenTcp将选择一个可用的端口,调用者可以利用TCPListener的addr方法来获取该地址.
func (l *TCPListener) Accept() (Conn,error)//实现listener接口的accept方法,它等待下次调用并返回一个连接
func (l *TCPListener) AcceptTCP() (*TCPConn,error)//接受下一次调用,并返回一个新的连接
func (l *TCPListener) Addr() Addr//返回listener的网络地址,TCPAddr
func (l *TCPListener) Close() error //停止监听TCP地址,已经建立的连接不被关闭
func (l *TCPListener) File() (f *os.File,err error)//返回底层os.File的一个副本,设定为阻塞模式,调用者需要关闭文件当完毕后,关闭l不影响文件副本f,并且关闭文件副本f也不影响tcplistener l,返回的文件句柄不同于原来网络连接的文件,通过这个副本来改变原来的文件属性可能起作用也可能不起作用.
func (l *TCPListener) SetDeadline(t time.Time) error//设定监听者的超时时间,如果时间设置为0,则禁用超时设置,即永远不会超时.
type UDPAddr //代表一个udp端口的地址
- type UDPAddr struct {
- IP IP
- Port int
- Zone string // IPv6 寻址范围
- }
func ResolveUDPAddr(net,addr string) (*UDPAddr,error) //将addr作为UDP地址解析并返回。参数addr格式为"host:port"或"[ipv6-host%zone]:port",解析得到网络名和端口名;net必须是"udp"、"udp4"或"udp6"。IPv6地址字面值/名称必须用方括号包起来,如"[::1]:80"、"[ipv6-host]:http"或"[ipv6-host%zone]:80"。
func (a *UDPAddr) Network() string//返回地址的网络名"udp"
func (a *UDPAddr) String() string//UDPAddr的字符化形式表示
type UDPConn //实现了udp网络连接,它实现了conn和packetconn的接口
func DialUDP(net string,raddr *UDPAddr) (*UDPConn,error)//连接网络上的远程地址raddr,其中net必须是udp,udp4或者udp6,如果laddr不是空,则使用本地地址用于连接
func ListenMulticastUDP(net string,ifi *Interface,gaddr *UDPAddr) (*UDPConn,error)//监听在ifi的组地址gaddr上的多播udp包,ifi指定了加入的接口,如果ifi是空的话,则使用默认的多播接口
func ListenUDP(net string,laddr *UDPAddr) (*UDPConn,error)//监听绑定在本地地址laddr上的udp包,如果laddr是端口0的话,则listenudp将选择一个可用的port端口,使用udpconn的LocalAddr方法能够发现这个port端口,返回的udpconn的ReadFrom和WriteTo方法能够用来接受和发送udp包.
func (c *UDPConn) Close() error//关闭连接
func (c *UDPConn) File() (f *os.File,err error)//与TCPConn中File()方法类似
func (c *UDPConn) LocalAddr() Addr//返回本地网络地址
func (c *UDPConn) Read(b []byte) (int,error)
func (c *UDPConn) ReadFrom(b []byte) (int,Addr,error)
func (c *UDPConn) ReadFromUDP(b []byte) (n int,addr *UDPAddr,err error)//从c中读取一个包,将有效负载写入b中返回写入的byte数以及包的地址.ReadFromUdp可以设置为超时.
func (c *UDPConn) ReadMsgUDP(b,oob []byte) (n,oobn,flags int,err error)//ReadMsgUDP从c读取一个数据包,将有效负载拷贝进b,相关的带外数据拷贝进oob,返回拷贝进b的字节数,拷贝进oob的字节数,数据包的flag,数据包来源地址和可能的错误。
func (c *UDPConn) RemoteAddr() Addr//返回远程的网络地址
func (c *UDPConn) SetDeadline(t time.Time) error //实现conn的超时方法,设置udpconn的超时
func (c *UDPConn) SetReadBuffer(bytes int) error
func (c *UDPConn) SetReadDeadline(t time.Time) error
func (c *UDPConn) SetWriteBuffer(bytes int) error
func (c *UDPConn) SetWriteDeadline(t time.Time) error
func (c *UDPConn) Write(b []byte) (int,error)
func (c *UDPConn) WriteMsgUDP(b,oob []byte,addr *UDPAddr) (n,oobn int,err error)//WriteMsgUDP通过c向地址addr发送一个数据包,b和oob分别为包有效负载和对应的带外数据,返回写入的字节数(包数据、带外数据)和可能的错误。
func (c *UDPConn) WriteTo(b []byte,addr Addr) (int,error)
func (c *UDPConn) WriteToUDP(b []byte,addr *UDPAddr) (int,error) //通过c将一个udp包写入addr,其中需要从b中复制有效负载.WriteToUDP也可以设置超时时间
type UnixAddr //代表一个Unix域名的socket终端地址
- type UnixAddr struct {
- Name string
- Net string
- }
func ResolveUnixAddr(net,addr string) (*UnixAddr,error) //将addr解析成UnixAddr,net指的是网络名称,为unix,unixgram或者unixpacket
func (a *UnixAddr) Network() string //返回网络名称,unix,unixgram或者unixpacket
func (a *UnixAddr) String() string //UnixAddr的字符形式表示
type UnixConn//UnixConn是Unix域名socket的网络连接
func DialUnix(net string,raddr *UnixAddr) (*UnixConn,error)//在网络协议net上连接本地地址laddr和远端地址raddr.其中net是"unix"、"unixgram"、"unixpacket",如果laddr不是nil将使用它作为本地地址。
func ListenUnixgram(net string,laddr *UnixAddr) (*UnixConn,error)//监听绑定到本地地址laddr的数据包,其中net必须是unixgram,返回连接的ReadFrom和WriteTo方法能够用来接受和发送地址包
func (c *UnixConn) Close() error//关闭连接
func (c *UnixConn) CloseRead() error//关闭连接的读操作,大多数情况下使用Close
func (c *UnixConn) CloseWrite() error//关闭连接的写操作,大多数情况下使用Close
func (c *UnixConn) File() (f *os.File,err error)//
func (c *UnixConn) LocalAddr() Addr
func (c *UnixConn) Read(b []byte) (int,error)
func (c *UnixConn) ReadFrom(b []byte) (int,error)
func (c *UnixConn) ReadFromUnix(b []byte) (n int,addr *UnixAddr,err error)
func (c *UnixConn) ReadMsgUnix(b,err error)
func (c *UnixConn) RemoteAddr() Addr
func (c *UnixConn) SetDeadline(t time.Time) error
func (c *UnixConn) SetReadBuffer(bytes int) error
func (c *UnixConn) SetReadDeadline(t time.Time) error
func (c *UnixConn) SetWriteBuffer(bytes int) error
func (c *UnixConn) SetWriteDeadline(t time.Time) error
func (c *UnixConn) Write(b []byte) (int,error)
func (c *UnixConn) WriteMsgUnix(b,addr *UnixAddr) (n,err error)
func (c *UnixConn) WriteTo(b []byte,addr Addr) (n int,err error)
func (c *UnixConn) WriteToUnix(b []byte,addr *UnixAddr) (n int,err error)
type UnixListener//表示一个Unix域名socket监听者,客户端应该使用指定的不同类型的listener而不是使用默认的unix domain socket
func ListenUnix(net string,laddr *UnixAddr) (*UnixListener,error) //利用Unix domain socket的laddr创建一个unix监听者,这个网络必须是unix或者unixpacket
func (l *UnixListener) Accept() (c Conn,err error)//
func (l *UnixListener) AcceptUnix() (*UnixConn,error)
func (l *UnixListener) Addr() Addr
func (l *UnixListener) Close() error
func (l *UnixListener) File() (f *os.File,err error)
func (l *UnixListener) SetDeadline(t time.Time) (err error)
Bugs
在任何POSIX平台上,使用ReadFrom或ReadFromIP方法从"ip4"网络读取数据时,即使有足够的空间,都可能不会返回完整的IPv4数据包,包括数据包的头域。即使Read或ReadMsgIP方法可以返回完整的数据包,也有可能出现这种情况。因为对go 1的兼容性要求,这个情况无法被修正。因此,如果必须获取完整数据包时,建议不要使用这两个方法,请使用Read或ReadMsgIP代替。
在OpenBSD系统中,在"tcp"网络监听时不会同时监听IPv4和IPv6连接。因为该系统中IPv4通信不会导入IPv6套接字中。如果有必要的话,请使用两个独立的监听。