乐趣区

【每日笔记】【Go学习笔记】2019-01-16 go网络编程

作者:施洪宝
一. 介绍

1.codis 使用了 go 中 martini 这个 web 框架
martinie github 地址: https://github.com/go-martini…

2.martini 主要是利用 go 标准库中的 net 包以及 net/http 包

二. net 包

1.net 包文档

官方文档: https://golang.org/pkg/net/

中文文档: https://studygolang.com/pkgdoc

2. 官方文档中已经说明了如何使用 net 包实现 tcp 服务端监听
ln, err := net.Listen(“tcp”, “:8080”)
if err != nil {
// handle error
}
for {
conn, err := ln.Accept()
if err != nil {
// handle error
}
go handleConnection(conn)
}

从使用库的一方来看, 接受连接的操作是阻塞式的, 使用方只需按照阻塞式网络编程进行处理即可
由于 go 有自己的协程调度, 在接受网络连接时, 实际使用的是 IO 多路复用, 具体则是通过 sysmon 线程进行操作
由于 go 具有垃圾自动回收以及协程, 故而针对每个网络请求, 开启单独协程进行处理

三. net/http 包

对于 http 服务, go 提供了 net/http 包可以直接使用

官方文档: https://golang.org/pkg/net/ht…

中文文档: https://studygolang.com/pkgdoc

使用示例 (net/http 包中还有其他方式构建 http 服务, 具体情况参考官方文档)
http.Handle(“/foo”, fooHandler)
http.HandleFunc(“/bar”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, “Hello, %q”, html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(“:8080”, nil))

http.Handle, http.HandleFunc 用于向 DefaultServeMux 注册处理函数
http.ListenAndServe 用于启动 http 服务, 当第二个参数为 nil 时, 表示使用默认的 DefaultServeMux 处理 http 请求

3.1 源码简介

1.go 采用 1.11.4, 不同的版本实现可能不同, 源码参见 src/net/http/server.go
2. 结构体定义

type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
hosts bool // whether any patterns contain hostnames
}
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
//http 请求处理接口
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
3. 函数定义
func Handle(pattern string, handler Handler)
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
func ListenAndServe(addr string, handler Handler) error

4. 基本流程

通过 http.Handle 或者 http.HandleFunc, 向 DefaultServeMux 中注册一些 url 相关的处理函数
通过 http.ListenAndServe 启动 web 服务
客户端发送 http 请求后, 服务端接受请求, 创建协程处理请求 (找到最匹配的 url 并调用之前设置的处理函数)

退出移动版