go语言net/http的代码流程

8 篇文章 0 订阅

net/http包介绍

http.HandleFunc 注册路由的函数
http.ListenAndServe 启动HTTP服务的函数

http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
	})
http.ListenAndServe(":8080", nil)

注册路由:

过程:
http.HandleFunc: 提供注册路由的接口—>
(mux *ServeMux) HandleFunc: 调用本身处理函数—>
(mux *ServeMux) Handle: 调用注册路由函数的服务

// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// 使用多路复用器注册路由绑定处理函数  DefaultServeMux:默认的多路复用器
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler) //调用
}
// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
   if handler == nil {
      panic("http: nil handler")
   }
   mux.Handle(pattern, HandlerFunc(handler)) //调用自身的服务
}
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
   mux.mu.Lock()
   defer mux.mu.Unlock()

   if pattern == "" {
      panic("http: invalid pattern")
   }
   if handler == nil {
      panic("http: nil handler")
   }
   if _, exist := mux.m[pattern]; exist {
      panic("http: multiple registrations for " + pattern)
   }

   if mux.m == nil {
      mux.m = make(map[string]muxEntry)
   }
   e := muxEntry{h: handler, pattern: pattern}
   mux.m[pattern] = e 
   if pattern[len(pattern)-1] == '/' {
      mux.es = appendSorted(mux.es, e)
   }

   if pattern[0] != '/' {
      mux.hosts = true
   }
}
DefaultServeMux(默认的多路复用器)的由来
// 以下来自谷歌对源码注释 翻译
// ServeMux 是一个 HTTP 请求多路复用器。
// 它将每个传入请求的 URL 与已注册的列表进行匹配
// 模式并调用该模式的处理程序
// 与 URL 最接近。
type ServeMux struct {
	mu    sync.RWMutex		
	m     map[string]muxEntry // 多路输入
	es    []muxEntry // slice of entries sorted from longest to shortest. (从最长到最短排序的条目切片。)
	hosts bool       // whether any patterns contain hostnames  (是否有路由模式包含主机名)
}

type muxEntry struct { //多路输入
	h       Handler
	pattern string
}

// NewServeMux allocates and returns a new ServeMux. (NewServeMux 分配并返回一个新的 ServeMux。)
func NewServeMux() *ServeMux { return new(ServeMux) }

// DefaultServeMux is the default ServeMux used by Serve. (DefaultServeMux 是 Serve 使用的默认 ServeMux。)
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux

服务监听 响应

总体流程
1.建立socket
2.bind,listen,accept
3.处理
函数调用过程:
http.ListenAndServe: 外部接口—>
(srv *Server) ListenAndServe() 监听并处理—>
net.Listen(network, address string) 收听本地网络地址上的通告.—>
(srv *Server) Serve(l net.Listener) 为Listener接受的连接创建一个协程go c.serve(connCtx),由新建立的读取请求调用handler处理—>
go c.serve(connCtx) : 开启一个协程专门处理具体的请求消息 —>
(c *conn) serve —> serverHandler{c.server}.ServeHTTP(w, w.req)
(sh serverHandler) ServeHTTP: 处理请求---->
(mux *ServeMux) ServeHTTP: 将请求分派给处理程序 —>
h, _ := mux.Handler® —>
h.ServeHTTP(w, r) 回调处理请求

总体:
ln, err := net.Listen(“tcp”, addr)做了初试化了socket, bind, listen的操作.
rw, e := l.Accept()进行accept, 等待客户端进行连接
go c.serve(ctx) 启动新的goroutine来处理本次请求. 同时主goroutine继续等待客户端连接, 进行高并发操作
h, _ := mux.Handler® 获取注册的路由, 然后拿到这个路由的handler, 然后将处理结果返回给客户端

Handler — A Handler responds to an HTTP request.(处理程序响应 HTTP 请求)

//一个处理 HTTP 请求的接口
type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

HandlerFunc — 本质上是一个函数类型,实现了Handler接口能够处理http请求

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).           [实现Handler接口]
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值