golang 建立web服务器 http包源码详解

golang 建立web服务器 http包源码详解

首先,熟悉http协议的都知道,http协议是基于TCP实现的。

http服务器的工作方式大概就是监听socket端口,接受连接,获取到请求,处理请求,返回响应。

所以,对应的会有几个部分

  • Request:用户请求的信息。post、get、url等这些信息

  • Response: 返回给客户端的信息

  • Conn: 用户每次的连接请求

  • Handler:处理请求和返回信息的逻辑处理

1. 搭建简单的web服务器

用golang可以很快地建立一个Web服务器

// httpWeb project main.go
package main

import (
    "fmt"
    "log"
    "net/http"
    "strings"
)

func HandleRequest(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    fmt.Println(r.Form)
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["bookId"])
    for k, v := range r.Form {
        fmt.Printf("key: %s, value: %s \n", k, strings.Join(v, " "))
    }
    fmt.Fprintf(w, "Respone message: Server get bookId successed....")
}

func main() {
    http.HandleFunc("/", HandleRequest)
    err := http.ListenAndServe(":6666", nil)
    if err != nil {
        log.Fatal("ListenError:", err)
    }
}

当输入 localhost:6060/?bookId=2222&bookId=6666 ,就会连接到该服务器,效果如下:

request

服务接收请求。至于二次请求favicon.ico的问题暂不讨论。

server

这样子,简单的一个web服务器就可以运行,处理简单的用户请求。


2. http包源码探究

只是这样子知道怎么搭起一个web服务器并不能满足对技术的好奇心

想要了解简单的几行代码是如何就建立起一web服务器的?

最好的方法就是直接读源代码,让代码来告诉我们实现的原理

回到一开始的web服务器,仔细想想,基本上是两个函数撑起整个Web服务器啊!

居然如此简洁!!

http.HandleFunc("/", HandleRequest)

http.ListenAndServe(":6666", nil)

不难理解,大概就是处理请求的函数,和监听端口。

首先,先分析一下http.HandleFunc()这个函数。

直接进入函数HandleFunc的声明,源码如下

// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}

这里DefaultServeMux调用了HandleFunc()

参数就是传进来的“/”HandleFunc(定义一个函数类型,就可以把函数作为参数传入)

对于DefaultServeMux在源代码中的声明如下

type ServeMux struct {
    mu    sync.RWMutex
    m     map[string]muxEntry
    hosts bool // whether any patterns contain hostnames
}

type muxEntry struct {
    explicit bool
    h        Handler
    pattern  string
}

// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { 
    return &ServeMux{m: make(map[string]muxEntry)} 
}

// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux()

可以看到,DefaultServeMux是一个默认的ServerMux,而ServeMux的结构体中,mu sync.RWMutex是一个并发控制的锁,一个装有muxEntry结构的map,一个hosts判断是否包含主机名。

!!!仔细一看,这个muxEntry结构体,其中一个变量h Handler和另一个变量pattern string

而这个Handler定义如下

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

是一个接口!!方法是ServeHTTP(ResponseWriter, *Request)

总结一下

DefaultServeMux的代码看完,大概清楚了。DefaultServeMux是一个ServerMux结构,这个结构里面最最主要包含一个map[string]muxEntry,map里面的每个muxEntry又包含一个string类型的变量pattern和一个接口Handler,这个接口里面的方法是ServeHTTP(ResponseWriter, *Request)。

好了,了解完DefaultServeMux,继续进入它调用的函数。

// HandleFunc registers the handler function for the given patter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值