Contents

go标准库-Net

go语言中文网

godoc

go语言中文网有很多文档缺少内容比如string.Builder就没有,godoc绝对详尽,推荐阅读godoc

简介

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

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

Dial函数和服务端建立连接:

1
2
3
4
5
6
7
conn, err := net.Dial("tcp", "google.com:80")
if err != nil {
	// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...

Listen函数创建的服务端:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
ln, err := net.Listen("tcp", ":8080")
if err != nil {
	// handle error
}
for {
	conn, err := ln.Accept()
	if err != nil {
		// handle error
		continue
	}
	go handleConnection(conn)
}

http

http包提供了HTTP客户端和服务端的实现

简介

客户端API

简单请求
1
2
3
4
5
6
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
	url.Values{"key": {"Value"}, "id": {"123"}})

请求后需要关闭请求体(类似关闭文件流)

1
2
3
4
5
6
7
resp, err := http.Get("http://example.com/")
if err != nil {
	// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...
复杂请求

管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
client := &http.Client{
	CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:

1
2
3
4
5
6
tr := &http.Transport{
	TLSClientConfig:    &tls.Config{RootCAs: pool},
	DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")

Client和Transport能够被安全并发复用

Server,Handler,ServeMux和HandlerFunc

https://5b0988e595225.cdn.sohucs.com/images/20171206/02f6a7ff47114f5ab1a9eb8af06d95bd.jpeg

type Handler interface接口是图中的处理器,它只有一个方法ServeHTTP(ResponseWriter, *Request)

Server和ServeMux是两个结构体类型

Server用于定义运行HTTP服务端的参数,Server里面包含一个Handler接口类型字段,该字段通常是一个ServeMux,不过HandleFunc类型也实现了这个接口,所以理论上设置为HandleFunc也是可以的,但是这样就不能进行多路复用了,就是说你这个服务就只有一个路由,因为HandleFunc类型是不支持注册路由的

ServeMux是HTTP请求的多路转接器(如图),实现了Handler接口类型,就和gin框架中的gin.Default的功能是一样的用于注册Handler接口对象,可以直接使用,甚至DefaultServeMux就只是通过var defaultServeMux ServeMux定义的,我们也可以自己定义。使用HandleFunc(pattern string, handler func(ResponseWriter, *Request))和Handle(pattern string, handler Handler)方法添加Handler接口对象,ServeMux是可以进行串联的

type HandlerFunc func(ResponseWriter, *Request)是实现了Handler接口的类型,其实就是一个具有特殊签名的函数

总结一下写一个web服务器的过程就是:

  1. 定义一个ServeMux多路转接器
  2. 向ServeMux注册Handler接口对象(可以是ServeMux或者HandlerFunc)
  3. 定义一个Server对象,设置运行HTTP服务端的参数,并把定义的ServeMux作为Server对象的Handler类型字段
  4. 调用Server对象的ListenAndServe方法启动服务端

type Server struct

变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
type Server struct {
    Addr           string        // 监听的TCP地址,如果为空字符串会使用":http"
    Handler        Handler       // 调用的处理器,如为nil会调用http.DefaultServeMux
    ReadTimeout    time.Duration // 请求的读取操作在超时前的最大持续时间
    WriteTimeout   time.Duration // 回复的写入操作在超时前的最大持续时间
    MaxHeaderBytes int           // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可选的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
    // 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
    // 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
    // 连接在函数返回时会自动关闭。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
    // 参见ConnState类型和相关常数获取细节。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
    // 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
    ErrorLog *log.Logger
    // 内含隐藏或非导出字段
}

方法

  • func (s *Server) SetKeepAlivesEnabled(v bool):设置是否复用TCP连接,默认启用
  • func (srv *Server) Serve(l net.Listener) error:监听l对应的端口并启动服务
  • func (srv *Server) ListenAndServe() error:监听addr字段对应的端口并启动服务
  • func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error:设置https协议中TLS层的证书文件和私钥文件,并调用ListenAndServe()方法

type Handler interface

实现了Handler接口的对象可以注册到HTTP服务端,为特定的路径及其子树提供服务

方法

  • ServeHTTP(ResponseWriter, *Request)

type ServeMux struct

ServeMux类型是HTTP请求的多路转接器。它会将每一个接收的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的Handler

方法

  • func (mux *ServeMux) Handle(pattern string, handler Handler):注册Handler并配置路由pattern
  • func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)):注册HandleFunc配置路由pattern
  • func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request):该ServeMux下的处理器

type HandlerFunc func(ResponseWriter, *Request)

方法

  • func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request):处理器

pprof

pprof包通过它的HTTP服务端提供pprof可视化工具期望格式的运行时剖面文件数据服务。内部是调用runtime/pprof

1
import _ "net/http/pprof"

然后启动默认的http服务就行了

1
2
3
go func() {
	log.Println(http.ListenAndServe("localhost:6060", nil))
}()

pprof工具查看监控状态

  • go tool pprof http://localhost:6060/debug/pprof/heap
  • go tool pprof http://localhost:6060/debug/pprof/profile
  • go tool pprof http://localhost:6060/debug/pprof/block

web pprof:http://localhost:6060/debug/pprof/

url

url包解析URL并实现了查询的逸码,参见RFC 3986

函数

  • func Parse(rawURL string) (*URL, error):转换字符串为url结构体
  • func QueryEscape(s string) string:对s进行转码
  • func QueryUnescape(s string) (string, error):对s进行解码

type URL struct

变量

  • Host string:host或host:port
  • Path string:路径
  • RawQuery string:编码后的查询字符串,没有’?’,通常通过Value结构体给这个字段赋值:rawUrl.RawQuery = params.Encode(),也可以使用未编码的字符串:rawUrl.RawQuery, err = url.QueryUnescape(params.Encode())
  • User *Userinfo:用户名和密码信息

方法

  • func (u *URL) String() string:转换为合法url

type Values map[string][]string

Values将建映射到值的列表。它一般用于查询的参数和表单的属性。不同于http.Header这个字典类型,Values的键是大小写敏感的

方法

  • func (v Values) Get(key string) string
  • func (v Values) Set(key, value string)
  • func (v Values) Add(key, value string)
  • func (v Values) Del(key string)
  • func (v Values) Encode() string:将值编码后用&将键值对串起来
 |