• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go标准库的学习-net

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

参考:https://studygolang.com/pkgdoc

导入方式:

import "net"

net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。

虽然本包提供了对网络原语的访问,大部分使用者只需要Dial、Listen和Accept函数提供的基本接口;以及相关的Conn和Listener接口。crypto/tls包提供了相同的接口和类似的Dial和Listen函数。

1)IP

type IP

type IP []byte

IP类型是代表单个IP地址的[]byte切片。本包的函数都可以接受4字节(IPv4)和16字节(IPv6)的切片作为输入。

注意,IP地址是IPv4地址还是IPv6地址是语义上的属性,而不取决于切片的长度:16字节的切片也可以是IPv4地址。

 

func IPv4

func IPv4(a, b, c, d byte) IP

IPv4返回包含一个IPv4地址a.b.c.d的IP地址(16字节格式)。

func ParseIP

func ParseIP(s string) IP

ParseIP将s解析为IP地址,并返回该地址。如果s不是合法的IP地址文本表示,ParseIP会返回nil。

字符串可以是小数点分隔的IPv4格式(如"74.125.19.99")或IPv6格式(如"2001:4860:0:2001::68")格式。

举例:

package main 
import(
    "fmt"
    "net"
    "reflect"
)

var parseIPTests = []struct {
    in  string
    out net.IP
}{
    {"127.0.1.2", net.IPv4(127, 0, 1, 2)},
    {"127.0.0.1", net.IPv4(127, 0, 0, 1)},
    {"127.001.002.003", net.IPv4(127, 1, 2, 3)},
    {"::ffff:127.1.2.3", net.IPv4(127, 1, 2, 3)},
    {"::ffff:127.001.002.003", net.IPv4(127, 1, 2, 3)},
    {"::ffff:7f01:0203", net.IPv4(127, 1, 2, 3)},
    {"0:0:0:0:0000:ffff:127.1.2.3", net.IPv4(127, 1, 2, 3)},
    {"0:0:0:0:000000:ffff:127.1.2.3", net.IPv4(127, 1, 2, 3)},
    {"0:0:0:0::ffff:127.1.2.3", net.IPv4(127, 1, 2, 3)},

    {"2001:4860:0:2001::68", net.IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
    {"2001:4860:0000:2001:0000:0000:0000:0068", net.IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},

    {"-0.0.0.0", nil},
    {"0.-1.0.0", nil},
    {"0.0.-2.0", nil},
    {"0.0.0.-3", nil},
    {"127.0.0.256", nil},
    {"abc", nil},
    {"123:", nil},
    {"fe80::1%lo0", nil},
    {"fe80::1%911", nil},
    {"", nil},
    {"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628
}

func main() {
    for i, tt := range parseIPTests {
        if out := net.ParseIP(tt.in); !reflect.DeepEqual(out, tt.out) {//如果得到的out与上面的结构体中out的值不等的话,就返回错误
            fmt.Errorf("ParseIP(%q) = %v, want %v", tt.in, out, tt.out)
        } else{
            fmt.Printf("%v out is : %v\n", i, out)
        }
        if tt.in == "" { //如果in为空,则跳出该循环,继续下一个循环
            fmt.Println("%v is \'\' ")
            continue
        }
        var out net.IP 
        //解码tt.in为IP,并将值输入out,如果该out与tt.out不等,或者运行UnmarshalText出错(即无out值)但tt.out不为nil,或者运行UnmarshalText没出错(即有out值)但tt.out为nil的情况下则报错
        if err := out.UnmarshalText([]byte(tt.in)); !reflect.DeepEqual(out, tt.out) || (tt.out == nil) != (err != nil) {
            fmt.Errorf("IP.UnmarshalText(%q) = %v, %v, want %v", tt.in, out, err, tt.out)
        }else{
            fmt.Printf("%v out is : %v\n", i, out)            
        }
    }
}

返回:

userdeMBP:go-learning user$ go run test.go 127.0.0.1
0 out is : 127.0.1.2
0 out is : 127.0.1.2
1 out is : 127.0.0.1
1 out is : 127.0.0.1
2 out is : 127.1.2.3
2 out is : 127.1.2.3
3 out is : 127.1.2.3
3 out is : 127.1.2.3
4 out is : 127.1.2.3
4 out is : 127.1.2.3
5 out is : 127.1.2.3
5 out is : 127.1.2.3
6 out is : 127.1.2.3
6 out is : 127.1.2.3
7 out is : 127.1.2.3
7 out is : 127.1.2.3
8 out is : 127.1.2.3
8 out is : 127.1.2.3
9 out is : 2001:4860:0:2001::68
9 out is : 2001:4860:0:2001::68
10 out is : 2001:4860:0:2001::68
10 out is : 2001:4860:0:2001::68
11 out is : <nil>
11 out is : <nil>
12 out is : <nil>
12 out is : <nil>
13 out is : <nil>
13 out is : <nil>
14 out is : <nil>
14 out is : <nil>
15 out is : <nil>
15 out is : <nil>
16 out is : <nil>
16 out is : <nil>
17 out is : <nil>
17 out is : <nil>
18 out is : <nil>
18 out is : <nil>
19 out is : <nil>
19 out is : <nil>
20 out is : <nil>
%v is \'\' 
21 out is : <nil>
21 out is : <nil>

 

func (IP) String

func (ip IP) String() string

String返回IP地址ip的字符串表示。如果ip是IPv4地址,返回值的格式为点分隔的,如"74.125.19.99";否则表示为IPv6格式,如"2001:4860:0:2001::68"。

举例:

package main 
import(
    "fmt"
    "os"
    "net"
)

func main() {
    if len(os.Args) != 2{
        fmt.Fprintf(os.Stderr, "Usage: %s ip-addr\n", os.Args[0])
        os.Exit(1)
    }
    name := os.Args[1]
    addr := net.ParseIP(name)
    if addr == nil {
        fmt.Println("Invalid address")
    }else{
        fmt.Println("the address is", addr.String())
    }
    os.Exit(0)
}

返回:

userdeMacBook-Pro:go-learning user$ go run test.go
Usage: /var/folders/2_/g5wrlg3x75zbzyqvsd5f093r0000gn/T/go-build258331112/b001/exe/test ip-addr
exit status 1
userdeMacBook-Pro:go-learning user$ go run test.go 127.0.0.1
the address is 127.0.0.1

 

func (IP) MarshalText

func (ip IP) MarshalText() ([]byte, error)

MarshalText实现了encoding.TextMarshaler接口,返回值和String方法一样。即将ip的值编码为[]byte类型返回

func (*IP) UnmarshalText

func (ip *IP) UnmarshalText(text []byte) error

UnmarshalText实现了encoding.TextUnmarshaler接口。IP地址字符串应该是ParseIP函数可以接受的格式。即将text的值解码为IP类型然后存储到ip中

举例:

package main 
import(
    "fmt"
    "net"
    "log"
    "reflect"
)
func main() {
    for _, in := range [][]byte{[]byte("127.0.1.2"), []byte("0:0:0:0:0000:ffff:127.1.2.3")} {
        var out = net.IP{1, 2, 3, 4}
        //err应该为nil,且out应该为nil,这样才不会报错,解码in的值将写到out中
        if err := out.UnmarshalText(in); err != nil || out == net.IP{1, 2, 3, 4} {
            fmt.Errorf("UnmarshalText(%v) = %v, %v; want nil, nil", in, out, err)
        }else{
            fmt.Printf("in is : %q, out is %v\n", in, out)
        }
    }
    var ip = net.IP{1, 2, 3, 4}
    //将ip编码为[]byte类型,返回got
    got, err := ip.MarshalText()
    if err != nil {
        log.Fatal(err)
    }
    //got应该等于[]byte("")
    if !reflect.DeepEqual(got, []byte("1.2.3.4")) {
        fmt.Errorf(`got %#v, want []byte("")`, got)
    }else{
        fmt.Printf("got is : %q\n", got)
    }
}

返回:

userdeMBP:go-learning user$ go run test.go 127.0.0.1
in is : "127.0.1.2", out is 127.0.1.2
in is : "0:0:0:0:0000:ffff:127.1.2.3", out is 127.1.2.3
got is : "1.2.3.4"

func (IP) IsGlobalUnicast

func (ip IP) IsGlobalUnicast() bool

如果ip是全局单播地址,则返回真。

func (IP) IsLinkLocalUnicast

func (ip IP) IsLinkLocalUnicast() bool

如果ip是链路本地单播地址,则返回真。

func (IP) IsInterfaceLocalMulticast

func (ip IP) IsInterfaceLocalMulticast() bool

如果ip是接口本地组播地址,则返回真。

func (IP) IsLinkLocalMulticast

func (ip IP) IsLinkLocalMulticast() bool

如果ip是链路本地组播地址,则返回真。

func (IP) IsMulticast

func (ip IP) IsMulticast() bool

如果ip是组播地址,则返回真。

func (IP) IsLoopback

func (ip IP) IsLoopback() bool

如果ip是环回地址,则返回真。

func (IP) IsUnspecified

func (ip IP) IsUnspecified() bool

如果ip是未指定地址,则返回真。

func (IP) Equal

func (ip IP) Equal(x IP) bool

如果ip和x代表同一个IP地址,Equal会返回真。代表同一地址的IPv4地址和IPv6地址也被认为是相等的。

func (IP) To16

func (ip IP) To16() IP

To16将一个IP地址转换为16字节表示。如果ip不是一个IP地址(长度错误),To16会返回nil。

func (IP) To4

func (ip IP) To4() IP

To4将一个IPv4地址转换为4字节表示。如果ip不是IPv4地址,To4会返回nil。

 

func (IP) DefaultMask

func (ip IP) DefaultMask() IPMask

函数返回IP地址ip的默认子网掩码。只有IPv4有默认子网掩码;如果ip不是合法的IPv4地址,会返回nil。

func (IP) Mask

func (ip IP) Mask(mask IPMask) IP

Mask方法认为mask为ip的子网掩码,返回ip的网络地址部分的ip。(主机地址部分都置0)

举例:

package main 
import(
    "fmt"
    "net"
    // "log"
    // "reflect"
)

func main() {
    var ip = net.IP{127, 168, 124, 1}
    fmt.Println(ip.DefaultMask()) //ff000000,即255.0.0.0
    fmt.Printf("%q\n", ip) //"127.168.124.1"
    //将子网掩码设为255.255.0.0后,返回的ip将会符合对应的子网掩码,所以返回"127.168.0.0"
    //如果设置的是255.0.0.0,则返回"127.0.0.0"
    ip = ip.Mask(net.IPv4Mask(255, 255, 0, 0)) 
    fmt.Printf("%q\n", ip) //"127.168.0.0"
}

 

type ParseError

type ParseError struct {
    Type string
    Text string
}

ParseError代表一个格式错误的字符串,Type为期望的格式。

func (*ParseError) Error

func (e *ParseError) Error() string

 

func ParseCIDR

func ParseCIDR(s string) (IP, *IPNet, error)

ParseCIDR将s作为一个CIDR(无类型域间路由)的IP地址和掩码字符串,如"192.168.100.1/24"或"2001:DB8::/48",解析并返回IP地址和IP网络,参见RFC 4632RFC 4291

本函数会返回IP地址和该IP所在的网络和掩码。例如,ParseCIDR("192.168.100.1/16")会返回IP地址192.168.100.1和IP网络192.168.0.0/16。

举例:

package main 
import(
    "fmt"
    "net"
    // "log"
    "reflect"
)

var parseCIDRTests = []struct {
    in  string
    ip  net.IP
    net *net.IPNet
    err error
}{
    {"135.104.0.0/32", net.IPv4(135, 104, 0, 0), &net.IPNet{IP: net.IPv4(135, 104, 0, 0), Mask: net.IPv4Mask(255, 255, 255, 255)}, nil},
    {"0.0.0.0/24", net.IPv4(0, 0, 0, 0), &net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(255, 255, 255, 0)}, nil},
    {"135.104.0.1/24", net.IPv4(135, 104, 0, 1), &net.IPNet{IP: net.IPv4(135, 104, 0, 0), Mask: net.IPv4Mask(255, 255, 255, 0)}, nil},
    {"::1/128", net.ParseIP("::1"), &net.IPNet{IP: net.ParseIP("::1"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))}, nil},
    {"abcd:2345::/127", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"))}, nil},
    {"abcd:2345::/65", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff:ffff:8000::"))}, nil},
    {"abcd:2345::/64", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff:ffff::"))}, nil},
    {"abcd:2345::/63", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff:fffe::"))}, nil},
    {"abcd:2345::/33", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:8000::"))}, nil},
    {"abcd:2345::/32", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2345::"), Mask: net.IPMask(net.ParseIP("ffff:ffff::"))}, nil},
    {"abcd:2344::/31", net.ParseIP("abcd:2344::"), &net.IPNet{IP: net.ParseIP("abcd:2344::"), Mask: net.IPMask(net.ParseIP("ffff:fffe::"))}, nil},
    {"abcd:2300::/24", net.ParseIP("abcd:2300::"), &net.IPNet{IP: net.ParseIP("abcd:2300::"), Mask: net.IPMask(net.ParseIP("ffff:ff00::"))}, nil},
    {"abcd:2345::/24", net.ParseIP("abcd:2345::"), &net.IPNet{IP: net.ParseIP("abcd:2300::"), Mask: net.IPMask(net.ParseIP("ffff:ff00::"))}, nil},
    {"2001:DB8::/48", net.ParseIP("2001:DB8::"), &net.IPNet{IP: net.ParseIP("2001:DB8::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff::"))}, nil},
    {"2001:DB8::1/48", net.ParseIP("2001:DB8::1"), &net.IPNet{IP: net.ParseIP("2001:DB8::"), Mask: net.IPMask(net.ParseIP("ffff:ffff:ffff::"))}, nil},
    {"192.168.1.1/255.255.255.0", nil, nil, &net.ParseError{Type: "CIDR address", Text: "192.168.1.1/255.255.255.0"}},
    {"192.168.1.1/35", nil, nil, &net.ParseError{Type: "CIDR address", Text: "192.168.1.1/35"}},
    {"2001:db8::1/-1", nil, nil, &net.ParseError{Type: "CIDR address", Text: "2001:db8::1/-1"}},
    {"-0.0.0.0/32", nil, nil, &net.ParseError{Type: "CIDR address", Text: "-0.0.0.0/32"}},
    {"0.0.0.-3/32", nil, nil, &net.ParseError{Type: "CIDR address", Text: "0.0.0.-3/32"}},
    {"0.0.0.0/-0", nil, nil, &net.ParseError{Type: "CIDR address", Text: "0.0.0.0/-0"}},
    {"", nil, nil, &net.ParseError{Type: "CIDR address", Text: ""}},
}

func main() {
    for i, tt := range parseCIDRTests {
        ip, net, err := net.ParseCIDR(tt.in)
        //如果返回的err不是nil或者自定义的net.ParseError,那么将报错
        if !reflect.DeepEqual(err, tt.err) {
            fmt.Errorf("ParseCIDR(%q) = %v, %v; want %v, %v", tt.in, ip, net, tt.ip, tt.net)
        }
        //ParseCIDR没出错,且返回的ip,net和给出的值都相等则成功,否则报错
        if err == nil{
            if !tt.ip.Equal(ip) || !tt.net.IP.Equal(net.IP) || !reflect.DeepEqual(net.Mask, tt.net.Mask) {
                fmt.Errorf("ParseCIDR(%q) = %v, {%v, %v}; want %v, {%v, %v}", tt.in, ip, net.IP, net.Mask, tt.ip, tt.net.IP, tt.net.Mask)
            }else{
                fmt.Printf("%v ParseCIDR(%q) = %v, {%v, %q}\n", i, tt.in, ip, net.IP, net.Mask)
            }            
        }

    }
}

返回:

userdeMBP:go-learning user$ go run test.go
0 ParseCIDR("135.104.0.0/32") = 135.104.0.0, {135.104.0.0, "ffffffff"}
1 ParseCIDR("0.0.0.0/24") = 0.0.0.0, {0.0.0.0, "ffffff00"}
2 ParseCIDR("135.104.0.1/24") = 135.104.0.1, {135.104.0.0, "ffffff00"}
3 ParseCIDR("::1/128
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap