参考: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 4632和RFC 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
请发表评论