go笔记【一】——http包

本文介绍如何使用Go语言快速搭建一个简单的Web服务器,包括监听端口、处理请求等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.建立简单的WEB服务器

func helloworld(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()       //解析表单参数
    fmt.Println(r.Form) //打印表单
    fmt.Fprintf(w, "Hello world!") //写入ResponseWriter返回客户端 
}

func main() {
    http.HandleFunc("/", helloworld)       //设置访问路由 任意地址匹配helloworld方法
    err := http.ListenAndServe(":1234", nil) //设置监听端口
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

运行上面这段代码,程序将监听1234端口的http请求。将请求交给helloworld方法进行处理。
helloworld方法解释请求中的参数并打印,返回Hello world到客户端。

二.WEB工作方式

1.监听请求

func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}

通过ListenAndServe设置监听地址及Handler后,将创建一个server并开始监听请求
server.ListenAndServe会调用一个Serve方法

2.创建连接

func (srv *Server) Serve(l net.Listener) error {
    defer l.Close()
    if fn := testHookServerServe; fn != nil {
        fn(srv, l)
    }
    var tempDelay time.Duration //接收失败后,将延迟一段时间再次执行

    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)
    ctx = context.WithValue(ctx, LocalAddrContextKey, l.Addr())
    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)//将请求交给这个连接进行处理,创建一个goroutine
    }
}

通过不断循环接收请求,并创建新的连接,调用serve处理请求。每一个请求都会创建一个goroutine,互不影响。
调用serve方法后,serve先在参数中取出Request。创建一个serverHandler并调用了它的ServeHTTP
serverHandler{c.server}.ServeHTTP(w, w.req)

3.处理请求

type serverHandler struct {
    srv *Server
}

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
    handler := sh.srv.Handler
    if handler == nil {//如果server没有handler则使用默认的multiplexer
        handler = DefaultServeMux
    }
    if req.RequestURI == "*" && req.Method == "OPTIONS" {
        handler = globalOptionsHandler{}
    }
    handler.ServeHTTP(rw, req)
}
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

取得server的handler进行处理请求,实现handler接口需要一个ServeHTTP方法,该方法就是最终处理请求的方法
在第一节中,我们并没有写ServeHTTP方法。但在http.HandleFunc("/", sayhelloName)中调用了HanleFunc

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    mux.Handle(pattern, HandlerFunc(handler))
}

HandleFunc为默认的multiplexer注册一个handler

三.总结

http.HandleFunc("/", helloworld)
err := http.ListenAndServe(":1234", nil) 

只调用了两个方法就可以让WEB服务器跑起来
HanleFunc为默认的MUX注册handler,将匹配地址与处理方法绑定起来。处理方法接收 http.ResponseWriter、*http.Request两个类型的参数,无返回值。
然后用http.ListenAndServe开启对某端口进行监听。

1.ListenAndServe调用serve进行循环接收请求
2.serve接收到请求后新建连接并用一个新的goroutine进行处理,调用连接的serve方法
3.con.serve调用server的handler进行处理请求。如果server没有handler则使用默认的MUX——DefaultServeMux

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值