先来一个例子吧:
程序运行起来,在Postman分别发送get(http://127.0.0.1:8888/sayHelloWorld?name=我是get请求)、post(http://127.0.0.1:8888/sayHelloWorld,name:我是post请求)请求:
一、Web工作方式的几个概念:
1.Request:用户请求的信息,用来解析用户的请求信息,包括post、get、cookie、url等信息。
2.Response:服务器需要反馈给客户端的信息。
3.Conn:用户的每次请求链接。
4Handler:处理请求和生产返回信息的处理逻辑。
5.ResponseWriter: 生成Response的接口。
6.ServeMux: 路由,ServeMux也是一种Handler
二、http包执行流程
1.创建Listen Socket 监听指定的端口,等待客户端请求到来。
2.Listen Socket接受客户端的请求,得到Client Socket,接下来通过Client Socket与客户端通信。
3.处理客户端的请求,首先从Client Socket 读取HTTP请求的协议头,如果是POST方法,还可以读取客户端提交的数 据,然后交给相应的handler处理请求,handle处理完毕准备好客户端需要的数据,通过Client Socket写给客户端。
三、Go代码执行流程(结合原码来看更容易理解)
1、首先调用http.HandleFunc("/",HandleRequest)
a. 调用了DefaultServerMux的HandleFunc
b.调用了DefaultServerMux的Handle
c.往DefaultServeMux的map[string]muxEntry中增加对应的handler和路由规则
2、其次调用http.ListenAndServe(":8888",nil)
a. 实例化Serverserver := &Server{Addr: addr, Handler: handler}
b. 调用了Server.ListenAndServe()
c. 调用了net.Listen("tcp", addr) 监听端口,底层用TCP协议搭建了一个服务,然后监听我们设置的端口
d. 启动一个for循环,在循环体中接受请求
e.对每个请求实例化一个Conn c := srv.newConn(rw)并且开启一个goroutine为这个请求进行服务
go c.serve(ctx)
f. 读取每个请求的内容w, err := c.readRequest(ctx)
g. 判断handler是否为空,如果没有设置handler,handler就设置为DefaultServeMux
h. 根据request选择handler 并且进入到这个handler的ServeHttp mux.handler(r).ServeHTTP(w, r)
i. 选择路由:
1)判断有没有路由满足这个request(循环遍历ServerMux的muxEntry)
2)如果有路由满足,调用这个路由handler的serveHttp
3)如果没有路由满足,调用NotFoundHandler的ServeHttp