关闭

Golang学习之net包介绍

标签: gonet
212人阅读 评论(0) 收藏 举报
分类:

       与大多数语言一样,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初始化了一个数组切片,并且指定了元素个数为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包的文档。

       转自:http://blog.csdn.net/cc7756789w/article/details/51014076

0
0
查看评论

golang标准库学习——buffio包

import "bufio" bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。 目录 一、常量 const ( // 用于缓冲一个token,...
  • weiyuefei
  • weiyuefei
  • 2015-12-05 16:30
  • 2487

golang中net包用法(一)

net包对于网络I/O提供了便携式接口,包括TCP/IP,UDP,域名解析以及Unix Socket。尽管net包提供了大量访问底层的接口,但是大多数情况下,客户端仅仅只需要最基本的接口,例如Dial,LIsten,Accepte以及分配的conn连接和listener接口。 crypto/tls包...
  • chenbaoke
  • chenbaoke
  • 2015-01-16 20:30
  • 10182

golang中net包用法

func Listen(net, laddr string) (Listener, error)  //返回在一个本地网络地址laddr上监听的Listener。网络类型参数net必须是面向流的网络:"tcp"、"tcp4"、"tcp6&q...
  • hellochenlu
  • hellochenlu
  • 2016-08-05 19:14
  • 400

Golang学习笔记 包和项目构成

工作目录先来说说Golang的工作目录,安装好Golang后,需要做的一件事情就是设置工作目录,所有的项目、工具、第三方包会存放到工作目录中。默认情况下工作目录是用户目录的go文件夹。我们可以利用环境变量GOPATH来更改Golang工作目录的位置。工作目录的结构是如下这样的。bin文件夹存放项目会...
  • u011054333
  • u011054333
  • 2017-06-01 21:11
  • 386

golang x/net/context包笔记

golang x/net/context包笔记基本是 https://blog.golang.org/context 的笔记,能翻墙的话,还是建议大家看看简介以前一直见到这个包,感觉很神秘,而context的意思让人觉得不知道它到底是干什么的。context包主要用于request请求。reques...
  • sryan
  • sryan
  • 2016-07-20 15:49
  • 3746

golang net包基础解析

这里主要介绍网络包内主要的几个类型。 net包是提供了底层的网络接口的,但是平时我们需要就是两个主要的接口,Listener和Conn。1. ConnConn是一个基本的接口类型,以数据流为向导的网络连接接口。注意他是接口类型,不需要我们来手动构造实现Conn接口。 生成满足Conn接口的类型的...
  • Wu_Roc
  • Wu_Roc
  • 2017-08-14 20:55
  • 272

Golang context包入门

Golang context包入门 转自:http://studygolang.com/articles/9624 概述 Golang 的 context Package 提供了一种简洁又强大方式来管理 goroutine 的生命周期,同时提供了一种 Requst-Scope K-...
  • yueguanyun
  • yueguanyun
  • 2017-03-22 09:22
  • 4419

go利用x/net/html包实现的蜘蛛

看了网上很多个spider版本, 几乎都是使用regexp包正则匹配实现. 其实使用DOC, 性能更好, 也更优雅 package main import ( "fmt" "net/http" "os" &...
  • black_OX
  • black_OX
  • 2016-07-21 10:46
  • 2019

Go net包介绍

与大多数语言一样,Go的标准库很全,因为Go的出现本来就是为了网络通信的高并发实现,所以其相关的网络库封装得更简洁,更Readable。这里来大致介绍几个网络库,掌握了学习方法,那么只要里面有那个库,你就能找到,就能快速了解怎么查阅。net.ResolveIPAddr()根据域名查找IP地址不得不感...
  • cc7756789w
  • cc7756789w
  • 2016-03-30 15:15
  • 2182

Golang学习之net/http包

使用net/http包快速创建一个HTTP服务器。// file http_test1.go package main import ( "fmt" "net/http" "log" )func HandleInde...
  • yxys01
  • yxys01
  • 2017-09-21 17:52
  • 301
    个人资料
    • 访问:193120次
    • 积分:4105
    • 等级:
    • 排名:第8984名
    • 原创:178篇
    • 转载:176篇
    • 译文:1篇
    • 评论:18条
    博客专栏
    最新评论