天天看点

gin源码解读1-net/http的大概流程

gin源码解读1-net/http的大概流程

router.Run()的源码:

然后看到开始调用的是http.ListenAndServe(address, engine), 这个函数是net/http的函数. 然后请求数据就在net/http开始流转.

所以, gin源码阅读系列就是要弄明白以下几个问题:

request数据是如何流转的

gin框架到底扮演了什么角色

请求从gin流入net/http, 最后又是如何回到gin中

gin的context为何能承担起来复杂的需求

gin的路由算法

gin的中间件是什么

gin的Engine具体是个什么东西

net/http的requeset, response都提供了哪些有用的东西

先不使用gin, 直接使用net/http来处理http请求

简单的说一下http请求是如何建立起来的(需要有基本的网络基础,socket编程)

gin源码解读1-net/http的大概流程

在TCP/IP五层模型下, HTTP位于应用层, 需要有传输层来承载HTTP协议. 传输层比较常见的协议是TCP,UDP, SCTP等. 由于UDP不可靠, SCTP有自己特殊的运用场景, 所以一般情况下HTTP是由TCP协议承载的(可以使用wireshark抓包然后查看各层协议)

使用TCP协议的话, 就会涉及到TCP是如何建立起来的. 面试中能够常遇到的名词三次握手, 四次挥手就是在这里产生的. 具体的建立流程就不在陈述了, 大概流程就是图中左半边

所以说, 要想能够对客户端http请求进行回应的话, 就首先需要建立起来TCP连接, 也就是socket. 下面要看下net/http是如何建立起来socket?

从图上可以看出, 不管server代码如何封装, 都离不开bind,listen,accept这些函数. 就从上面这个简单的demo入手查看源码.

这段代码是在注册一个路由及这个路由的handler到DefaultServeMux中

定义一个函数类型,对一个函数进行转型成一个类型,然后该类型实现一些方法,从而实现某些接口

可以看到这个路由注册太过简单了, 也就给gin, iris, echo等框架留下了扩展的空间, 后面详细说这个东西

上面路由已经注册到net/http了, 下面就该如何建立socket了, 以及最后又如何取到已经注册到的路由, 将正确的响应信息从handler中取出来返回给客户端

1.

<code>_ = http.ListenAndServe(":8080", nil)</code>

2.

这基本是整个过程的代码了. 基本上是:

ln, err := net.Listen("tcp", addr)做了初试化了socket, bind, listen的操作.

rw, e := l.Accept()进行accept, 等待客户端进行连接

go c.serve(ctx) 启动新的goroutine来处理本次请求. 同时主goroutine继续等待客户端连接, 进行高并发操作

h, _ := mux.Handler(r) 获取注册的路由, 然后拿到这个路由的handler, 然后将处理结果返回给客户端

从这里也能够看出来, net/http基本上提供了全套的服务.

从这段函数可以看出来, 匹配规则过于简单, 当能匹配到路由的时候就返回其对应的handler, 当不能匹配到时就返回/. 所以net/http的路由匹配无法满足复杂的需求开发. 所以基本所有的go框架干的最主要的一件事情就是重写net/http的route

所以我们直接说gin就是一个httprouter也不过分, 当然gin也提供了其他比较主要的功能, 后面会一一介绍

还有一个go框架要实现的东西是http.ResponseWriter

综述, net/http基本已经提供http服务的70%的功能, 那些号称贼快的go框架, 基本上都是提供一些功能, 让我们能够更好的处理客户端发来的请求.

参考链接