设为首页 加入收藏

TOP

Go语言备忘录(3):net/http包的使用模式和源码解析(一)
2017-10-21 06:06:49 】 浏览:752
Tags:语言 备忘录 net/http 包的 使用 模式 源码 解析

本文是晚辈对net/http包的一点浅显的理解,文中如有错误的地方请前辈们指出,以免误导!

转摘本文也请注明出处:Go语言备忘录(3):net/http包的使用模式和源码解析,多谢! 

目录:

 
一、http包的3个关键类型:
Handler接口:所有请求的处理器、路由ServeMux都满足该接口;
type Handler interface {
   ServeHTTP(ResponseWriter, *Request)
}
ServeMux结构体:HTTP请求的多路转接器(路由),它负责将每一个接收到的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的处理器。它内部用一个map来保存所有处理器Handler
  • http包有一个包级别变量DefaultServeMux,表示默认路由:var DefaultServeMux = NewServeMux(),使用包级别的http.Handle()、http.HandleFunc()方法注册处理器时都是注册到该路由中;
  • ServeMux结构体有ServeHTTP()方法(满足Handler接口),主要用于间接调用它所保存的处理器的ServeHTTP()方法
http.HandlerFunc函数类型:它满足Handler接口
type HandlerFunc func(ResponseWriter, *Request)
//实现Handler接口的ServeHTTP方法
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r) //调用自身
}

二、HTTP服务器的使用模式:
处理函数:只要函数的签名为 func(w http.ResponseWriter, r *http.Request) ,均可作为处理函数,即它可以被转换为http.HandlerFunc函数类型;

模式一:使用默认的路由来注册处理函数:
var addr = flag.String("addr", ":8080", "http server address")
//1.不带参数处理函数
func serveHome(w http.ResponseWriter, r *http.Request) {
   if r.URL.Path != "/" {
       http.NotFound(w, r)
       return
   }
   http.ServeFile(w, r, "home.html")
}
//2.带参数处理函数,闭包函数隐式转换为http.HandlerFunc函数类型
func myHandler(s string) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/" {
            http.NotFound(w, r)
            return
        }
        http.ServeFile(w, r, s) //使用参数s
    }
}
func main() {
   flag.Parse()
    
   //向默认路由注册处理器函数
   http.HandleFunc("/", serveHome) //或http.Handle("/", http.HandlerFunc(serveHome))
   http.Handle("/file",myHandler("somefile"))
    
   err := http.ListenAndServe(*addr, nil) //启动监听,第二个参数nil表示使用默认路由DefaultServeMux中注册的处理器
   if err != nil {
      log.Fatalln("ListenAndServe: ", err)
   }
}
 
模式二:使用自定义的路由来注册处理函数:
func main() {
  mux := http.NewServeMux() //新建一个自定义的路由
  mux.Handle("/file",myHandler("somefile"))
  mux.HandleFunc("/", serveHome) 
    
  err := http.ListenAndServe(*addr,mux) //启动监听
   if err != nil {
      log.Fatalln("ListenAndServe: ", err)
   }
}
 
模式三:直接自定义一个Server实例:该模式可以很方便的管理服务端的行为
 mux := http.NewServeMux()
 mux.Handle("/file",myHandler("somefile"))
 mux.HandleFunc("/", serveHome) 

 s := &http.Server{
    Addr: ":8080",
    Handler: mux, //指定路由或处理器,不指定时为nil,表示使用默认的路由DefaultServeMux
    ReadTimeout: 10 * time.Second,
    WriteTimeout: 10 * time.Second,
    MaxHeaderBytes: 1 << 20,
    ConnState: //指定连接conn的状态改变时的处理函数
        //....
 }
 log.Fatal(s.ListenAndServe())

 

接下来,我们就跟踪源码来仔细的分析下整个执行过程。


三、HTTP服务器的执行过程:
1.使用http.ListenAndServe()方法启动服务,它根据给定参数构造Server类型,然后调用server.ListenAndServe()
func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}

  
2.而server.ListenAndServe()方法内部调用net.Listen("tcp", addr),该方法内部又调用net.ListenTCP()创建并返回一个监听器net.Listener,如下的ln;

func (srv *Server) ListenAndServe() error {
    addr := srv.Addr
    if addr == "
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Golang:使用 httprouter 构建 AP.. 下一篇Go语言版本的helloworld

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目