go-net/http

go-net/http

文章摘要

net/http库的web工作原理大致就是如下四个部分组成了:端口监听、请求解析、路由分配、响应处理。更加代码化的说就是:创建 ServerSocket, 绑定并listen,accept连接,创建go线程服务一个连接。

归纳出流程图如下:

在这里插入图片描述

Go创建简单的web服务

package main

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

func main() {
   
    helloHandler := func(w http.ResponseWriter, req *http.Request) {
   
        fmt.Fprintf(w, "Hello, world!\n")
    }

    http.HandleFunc("/hello", helloHandler)
    log.Fatal(http.ListenAndServe(":9999", nil))
}

在这里插入图片描述

http包源码分析

在上面的代码中,起关键作用的函数为http.ListenAndServe,Go就是利用这个方法,实现了web服务中的端口监听、请求解析、路由分配、响应处理四大功能。

端口监听

查看http.ListenAndServe函数的源代码,位于server.go

// ListenAndServe listens on the TCP network address addr and then calls
// Serve with handler to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
//
// The handler is typically nil, in which case the DefaultServeMux is used.
//
// ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, handler Handler) error {
   
	server := &Server{
   Addr: addr, Handler: handler}
	return server.ListenAndServe()
}

查看Server.ListenAndServe

// ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
//
// If srv.Addr is blank, ":http" is used.
//
// ListenAndServe always returns a non-nil error. After Shutdown or Close,
// the returned error is ErrServerClosed.
func (srv *Server) ListenAndServe() error {
   
	if srv.shuttingDown() {
   
		return ErrServerClosed
	}
	addr := srv.Addr
	if addr == "" {
   
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	if err != nil {
   
		return err
	}
	return srv.Serve(ln)
}

可以看到,这里使用TCP协议创建了一个服务器,并监听特定的端口。

请求解析

顺应上面的代码,查看srv.Serve(ln)的源代码

// Serve accepts incoming connections on the Listener l, creating a
// new service goroutine for each. The service goroutines read requests and
// then call srv.Handler to reply to them.
//
// HTTP/2 support is only enabled if the Listener returns *tls.Conn
// connections and they were configured with "h2" in the TLS
// Config.NextProtos.
//
// Serve always returns a non-nil error and closes l.
// After Shutdown or Close, the returned error is ErrServerClosed.
func (srv *Server) Serve(l net.Listener) error {
   
	if fn := testHookServerServe; fn != nil {
   
		fn(srv, l) // call hook with unwrapped listener
	}

	origListener := l
	l = &onceCloseListener{
   Listener: l}
	defer l.Close()

	if err := srv.setupHTTP2_Serve(); err != nil {
   
		return err
	}

	if !srv.trackListener(&l, true) {
   
		return ErrServerClosed
	}
	defer srv.trackListener(&l, false)

	baseCtx := context.Background()
	if srv.BaseContext != nil {
   
		baseCtx = srv.BaseContext(origListener)
		if baseCtx == nil {
   
			panic("BaseContext returned a nil context")
		}
	}

	var tempDelay time.Duration // how long to sleep on accept failure

	ctx := context.WithValue(baseCtx, ServerContextKey, srv)
	for {
   
		rw, err := l.Accept()
		if err != 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
goroutine 342 [running]: sync.fatal({0xbdff5b, 0x20}) D:/Program Files (x86)/Go/src/runtime/panic.go:1031 +0x29 sync.(*RWMutex).Unlock(0x19f96d0) D:/Program Files (x86)/Go/src/sync/rwmutex.go:209 +0x57 go-study/models.sendMsg(0x0, {0x135fe0f0, 0x15, 0x15}) D:/go/go-study/models/Message.go:193 +0x70 go-study/models.Chat({0x12fe4500, 0x13bec360}, 0x130d0380) D:/go/go-study/models/Message.go:82 +0x3a0 go-study/service.SendUserMsg(0x13bec360) D:/go/go-study/service/userBasicService.go:237 +0x54 github.com/gin-gonic/gin.(*Context).Next(...) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1(0x13bec360) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/recovery.go:102 +0x89 github.com/gin-gonic/gin.(*Context).Next(...) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 github.com/gin-gonic/gin.LoggerWithConfig.func1(0x13bec360) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/logger.go:240 +0xa7 github.com/gin-gonic/gin.(*Context).Next(...) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/context.go:174 github.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0x13be80e0, 0x13bec360) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/gin.go:620 +0x51b github.com/gin-gonic/gin.(*Engine).ServeHTTP(0x13be80e0, {0xd04140, 0x13c060a0}, 0x130d0380) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gin-gonic/gin@v1.9.0/gin.go:576 +0x1c9 net/http.serverHandler.ServeHTTP({0x13d46000}, {0xd04140, 0x13c060a0}, 0x130d0380) D:/Program Files (x86)/Go/src/net/http/server.go:2947 +0x285 net/http.(*conn).serve(0x132d8360, {0xd048a0, 0x132f2738}) D:/Program Files (x86)/Go/src/net/http/server.go:1991 +0x67d created by net/http.(*Server).Serve D:/Program Files (x86)/Go/src/net/http/server.go:3102 +0x498
06-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值