Go net包介绍

原创 2016年03月30日 15:15:21

原文链接: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 main

import (
    "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.parseIPV4
undefined: 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初始化了一个数组切片,并且指定了元素个数为IPv6lenIPv6len被定义为常量:

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语言简单的TCP编程

前期准备 需要import "net"包IP类型,其中一个重要的方法是IP.ParseIP(ipaddr string)来判断是否是合法的IP地址 TCP Client func...
  • ygrx
  • ygrx
  • 2013年09月17日 15:21
  • 22325

go net 包详解1

/** * Created by Administrator on 13-12-9. */ package main import ( "fmt" "os" "net" ) /** *...

我为什么放弃Go语言

我为什么放弃Go语言?有好几次,当我想起来的时候,总是会问自己:这个决定是正确的吗?是明智和理性的吗?其实我一直在认真思考这个问题。开门见山地说,我当初放弃Go语言,就是因为两个“不爽”:第一,对Go...
  • liigo
  • liigo
  • 2014年04月14日 19:24
  • 337095

Go Web编程:http包分析

一个简单的web服务package mainimport ( "io" "log" "net/http" )func HelloGoServer(w http.Response...
  • uudou
  • uudou
  • 2016年10月05日 12:22
  • 2236

golang中net包用法

func Listen(net, laddr string) (Listener, error)  //返回在一个本地网络地址laddr上监听的Listener。网络类型参数net必须是面向流的网络:...

golang中net包用法(一)

net包对于网络I/O提供了便携式接口,包括TCP/IP,UDP,域名解析以及Unix Socket。尽管net包提供了大量访问底层的接口,但是大多数情况下,客户端仅仅只需要最基本的接口,例如Dial...

Go语言学习之net包(The way to go)

生命不止,继续go go go!!!不要问我net包和net/http包的区别,我们先会用,两者的区别慢慢去体会。net包有什么作用?Package net provides a portable i...

Go语言学习之net/url包(url相关操作)(the way to go)

生命不止,继续 go go go !!!今天跟大家分享的是是net/url package,从名字已经可以看出来了,与url相关的标准库。作用: Package url parses URLs an...

Go网络编程之net/http包执行流程源码分析

1. http包建立web服务器 package main import (     "fmt"     "log"     "net/http"     "stri...
  • huwh_
  • huwh_
  • 2017年07月30日 15:11
  • 387

Java网络通信常用类介绍(Java.net包)

InetAddress类:表示互联网协议 (IP) 地址 URL类:代表一个统一资源定位符,它是指向互联网“资源”的指针。    资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如...
  • pengkv
  • pengkv
  • 2014年12月18日 20:47
  • 5371
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Go net包介绍
举报原因:
原因补充:

(最多只允许输入30个字)