Go net包介绍
来源:互联网 发布:windows设置ntp服务器 编辑:程序博客网 时间:2024/05/05 05:11
原文链接:http://blog.csdn.net/cc7756789w/article/details/51014076
作者:牧歌
github:https://github.com/ZhangHang-z
转载请注明出处,未经作者允许不可用于商业目的。
与大多数语言一样,Go的标准库很全,因为Go的出现本来就是为了网络通信的高并发实现,所以其相关的网络库封装得更简洁,更Readable。
这里来大致介绍几个网络库,掌握了学习方法,那么只要里面有那个功能,你就能找到并快读查阅源码,了解其实现。
net.ResolveIPAddr()
根据域名查找IP地址
不得不感叹Go为开发者考虑良多,godoc这个工具真的很方便!先看下源码。
$ godoc -src net.ResolveIPAddr
func ResolveIPAddr(net, addr string) (*IPAddr, error) { if net == "" { net = "ip" } afnet, _, err := parseNetwork(net) if err != nil { return nil, err } switch afnet { case "ip", "ip4", "ip6": default: return nil, UnknownNetworkError(net) } addrs, err := internetAddrList(afnet, addr, noDeadline) if err != nil { return nil, err } return addrs.first(isIPv4).(*IPAddr), nil}
我们又从源码中学习了一招:case "ip", "ip4", "ip6"
。switch的一个case直接检测多个值的方法,如果不匹配则执行default中的代码。
可以看到,net和addr形参都接受string类型,而返回IPAddr的指针类型,和error类型的值。
来使用一下:
package mainimport ( "fmt" "net")func main() { addr, err := net.ResolveIPAddr("ip", "www.baidu.com") if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println(addr.IP)
输出:
注意看ResolveIPAddr的源码,如果你传给net的参数不是"ip", "ip4", "ip6"
其中的一个,那么err就不会是nil,而是UnknownNetworkError(net)
,错误的输出信息会是这样的: unknown network tcp
。
net.ParseIP()
检查IP地址格式是否有效
依照惯例,我们来看一下源码,$ godoc -src net ParseIP
:
func ParseIP(s string) IP { for i := 0; i < len(s); i++ { switch s[i] { case '.': return parseIPv4(s) case ':': ip, _ := parseIPv6(s, false) return ip } } return nil}
IPv4用.
号隔开,IPv6用:
号隔开,所以这个函数的内部又进行了判断其是IPv4还是IPv6。
注意:你不要手动去调用net.parseIPv4
或者net.parseIPv6
,会报如下错误:
cannot refer to unexported name net.parseIPV4undefined: net.parseIPV4
因为Go利用首字母的大小写来限制包外是否可访问,小写的函数或变量在包外无法访问到,就如同Java的public,private
修饰符。不过用godoc来获取小写开头的源码是没有问题的。
查看parseIPv4
的源码又发现:
func parseIPv4(s string) IP { // ... return IPv4(p[0], p[1], p[2], p[3])}
再追溯到IPv4上
func IPv4(a, b, c, d byte) IP { p := make(IP, IPv6len) copy(p, v4InV6Prefix) p[12] = a p[13] = b p[14] = c p[15] = d return p}
我们发现这些函数都返回了IP
对象,我们来看一下IP对象的定义: type IP []byte
其实就是一个自定义的数组切片类型。
IPv4
内部用make初始化了一个数组切片,并且指定了元素个数为IPv6len
。IPv6len
被定义为常量:
const ( IPv6len = 16)
然后进行将v4InV6Prefix
复制到到数组切片p
中,copy
的用法请自行搜索(注意copy的行为和常人的理解不同):
var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
至于储存IPv4的数组切片为什么要分配16个元素的大小,又复制给最后四个索引,可以看type IP []byte
的注释:
// An IP is a single IP address, a slice of bytes.// Functions in this package accept either 4-byte (IPv4)// or 16-byte (IPv6) slices as input.//// Note that in this documentation, referring to an// IP address as an IPv4 address or an IPv6 address// is a semantic property of the address, not just the// length of the byte slice: a 16-byte slice can still// be an IPv4 address.type IP []byte
这说了,一个16-byte
大小的数组可以仍然作为IPv4地址。创建数组切片slice1 := make([]int, 5)
其初始值都为0。
Go的源码不难,甚至比C简单,而且标准库的设计也非常规范。如果你需要使用更多的功能,可以查看net包的文档。
- Go net包介绍
- Go 常用包介绍
- Go net/http包
- go net 包详解1
- Go net/rpc 包总结
- go语言的os.exec包介绍
- Go语言学习之net包(The way to go)
- Go?GO!(三) Go的面向对象技术、并发和包的简单介绍
- 优秀.net 控件包介绍
- 【Go】包
- go利用x/net/html包实现的蜘蛛
- go语言net/http包解析http body之坑
- Go利用net/http包搭建Web服务器
- Go源码分析 net/http包分析:追溯到socket
- 七、GO语言库学习--net/url包--go语言笔记
- Go语言学习之net/http包(The way to go)
- Go语言学习之net/url包(url相关操作)(the way to go)
- NET下的流程图开发包介绍
- 获取验证码倒计时功能
- MYSQL级联条件删除数据
- 高通 MSM8K bootloader 之四: ramdump
- 高可用&负载均衡常用架构
- struts2文件上传获取文件名、文件类型
- Go net包介绍
- SQL server 中convert 函数转换日期格式
- Levenberg-Marquardt(LM算法)
- linux下环境变量、启动脚本、进程判断设置
- Android 设备管理器(DevicePolicyManager)
- sql 自定义函数
- Android error:No CPU/ABI system image available for this target
- 移动端css技巧
- 国外少儿PYTHON编程书推荐