go语言net/http源码解读

客户端和服务端

net/http代码块分为客户端和服务端两个部分。以下是net/http标准库的各个组成部分在客户端/服务中的划分:
在这里插入图片描述

http包的执行过程

如下图
在这里插入图片描述
服务端和服务端通信的过程:

  1. 服务端创建socket,绑定/监听指定的ip地址和端口,即Listen Socket
  2. 客户端与Listen Socket连接,Listen Socket接受客户端的请求,得到Client Socket,接下来通过Client Socket与客户端通信
  3. 创建go线程服务的一个连接,处理客户端的请求。首先从Client Socket读取HTTP请求的协议头,如果是POST方法,还可能要读取客户端提交的数据。然后交给相应的handler处理请求,handler处理完毕准备好客户端需要的数据, 通过Client Socket写给客户端
http服务器的执行过程

在这里插入图片描述

一个简单的服务器
package main

import (
	"fmt"
	"net/http"
)

func main() {
   
	http.HandleFunc("/hello", sayHello)
	http.ListenAndServe(":8080", nil)
}

func sayHello(res http.ResponseWriter, req *http.Request) {
   
	fmt.Fprintf(res, "hello")
}
注册路由

首先查看http.HandleFunc("/hello", sayHello)的源码:

// 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

type ServeMux struct {
   
	mu sync.RWMutex   // 锁,由于请求涉及到并发处理,因此这里需要一个锁机制
	m  map[string]muxEntry  //key是URL匹配字符串,muxEntry是对应的处理handler
	hosts bool // 路由匹配时,是否包含host
}

type muxEntry struct {
   
	h        Handler // 这个路由表达式对应哪个handler
	pattern  string  // 匹配字符串
}

// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux {
    return new(ServeMux) }

// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

ServeMux结构体:HTTP请求的多路转接器(路由),它负责将每一个接收到的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的处理器。它内部用一个map来保存所有处理器Handler。

DefaultServeMux,其实就是一个默认路由,是ServeMux的一个实例,使用包级别的http.Handle()http.HandleFunc()方法注册处理器时都是注册到该路由中。

再看DefaultServeMux.HandleFunc(pattern, handler)中的HandleFunc方法:

HandleFunc中调用ServerMuxHandleFunc()。将一个自定义的方法转换为一个一般Handler,最后再调用Server.Mux的handle()方法,完成URL与Handler的绑定,

// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
   
	if handler == nil {
   
		panic("http: nil handler")
	}
	mux.Handle(pattern, HandlerFunc(handler))

Handle方法将相关信息加入到map中:

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
   
	// 加一个写锁
	mux.mu.Lock()                
	defer mux.mu.</
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值