学习go的HTTP代码。先创建一个简单的web服务。

package main
 
import (
 "fmt"
 "log"
 "net/http"
)
 
func response(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello world!") //这个写入到w的是输出到客户端的
}
 
func main() {
 http.HandleFunc("/", response)
 err := http.ListenAndServe(":9000", nil)
 if err != nil {
  log.Fatal("ListenAndServe: ", err)
 }
}
http.HandleFunc("/", response)
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 DefaultServeMux.HandleFunc(pattern, handler)
}
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
 
type ServeMux struct {
 mu sync.RWMutex//读写锁。并发处理需要的锁
 m  map[string]muxEntry//路由规则map。一个规则一个muxEntry
 hosts bool //规则中是否带有host信息
}
一个路由规则字符串,对应一个handler处理方法。
type muxEntry struct {
 h  Handler
 pattern string
}
DefaultServeMuxServeMuxmuxEntryhttp.HandleFuncDefaultServeMux.HandleFuncmux.HandleHandlerFunc(handler)
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 mux.Handle(pattern, HandlerFunc(handler))
}
type Handler interface {
 ServeHTTP(ResponseWriter, *Request) // 路由实现器
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
 f(w, r)
}
HandlerFuncresponseServeHTTP
mux.Handle
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)
 }
 mux.m[pattern] = muxEntry{h: handler, pattern: pattern}
 
 if pattern[0] != '/' {
  mux.hosts = true
 }
}
handlerServeMux.mmapmapmuxEntryhandlerhttp.ListenAndServe(":9000", nil)
func ListenAndServe(addr string, handler Handler) error {
 server := &Server{Addr: addr, Handler: handler}
 return server.ListenAndServe()
}
 
func (srv *Server) ListenAndServe() error {
 addr := srv.Addr
 if addr == "" {
  addr = ":http"
 }
 ln, err := net.Listen("tcp", addr)
 if err != nil {
  return err
 }
 return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
}
net.Listen("tcp", addr)addrtcpKeepAliveListeneraddr
func (srv *Server) Serve(l net.Listener) error {
 defer l.Close()
 if fn := testHookServerServe; fn != nil {
  fn(srv, l)
 }
 var tempDelay time.Duration // how long to sleep on accept failure
 
 if err := srv.setupHTTP2_Serve(); err != nil {
  return err
 }
 
 srv.trackListener(l, true)
 defer srv.trackListener(l, false)
 
 baseCtx := context.Background() // base is always background, per Issue 16220
 ctx := context.WithValue(baseCtx, ServerContextKey, srv)
 for {
  rw, e := l.Accept()
  if e != nil {
   select {
   case <-srv.getDoneChan():
    return ErrServerClosed
   default:
   }
   if ne, ok := e.(net.Error); ok && ne.Temporary() {
    if tempDelay == 0 {
     tempDelay = 5 * time.Millisecond
    } else {
     tempDelay *= 2
    }
    if max := 1 * time.Second; tempDelay > max {
     tempDelay = max
    }
    srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
    time.Sleep(tempDelay)
    continue
   }
   return e
  }
  tempDelay = 0
  c := srv.newConn(rw)
  c.setState(c.rwc, StateNew) // before Serve can return
  go c.serve(ctx)
 }
}
forl.Accept()c := srv.newConn(rw)ConnConn(srv,rw)c.servec.serverdec.readRequest(ctx)serverHandler{c.server}.ServeHTTP(w, w.req)
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
 handler := sh.srv.Handler
 if handler == nil {
  handler = DefaultServeMux
 }
 if req.RequestURI == "*" && req.Method == "OPTIONS" {
  handler = globalOptionsHandler{}
 }
 handler.ServeHTTP(rw, req)
}
handlerListenAndServeDefaultServeMuxDefaultServeMuxDefaultServeMuxServeHTTPreponseServeHTTP

我们看下流程图

到此这篇关于“golang高并发的深入理解”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!