ListenAndServe阅读web
func ListenAndServe(addr string, handler Handler) error { //1. 建立server server := &Server{Addr: addr, Handler: handler} //2. 启动server return server.ListenAndServe() }
注意:建立一个server,启动server,咱们也能够按照这2个步骤去建立一个web服务安全
服务器
// 基类Closer接口,关闭全部连接中止服务 type Closer interface { Close() error } // 检查服务是否存活,里面定义了接口,接口的另类定义使用 // 奇怪的行为,不肯定为何这么作 func http2h1ServerKeepAlivesDisabled(hs *Server) bool { var x interface{} = hs // 临时定义接口,使用【奇怪的使用方法】 type I interface { doKeepAlives() bool } if hs, ok := x.(I); ok { return !hs.doKeepAlives() } return false } //Server // A Server defines parameters for running an HTTP server. // The zero value for Server is a valid configuration. type Server struct { Addr string // 监听的TCP地址 Handler Handler // 注册的路由处理方法 // 若是服务须要支持https协议 那么须要相应的配置 TLSConfig *tls.Config //读超时设置 ReadTimeout time.Duration // 读取请求头超时设置 ReadHeaderTimeout time.Duration // 写超时 WriteTimeout time.Duration // 请求直接最长的空闲时长 IdleTimeout time.Duration // 请求头最大的容量 MaxHeaderBytes int // HTTPS协议相关 TLSNextProto map[string]func(*Server, *tls.Conn, Handler) // 能够添回调函数,当客户端处于哪一个状态时候能够执行某些动做 ConnState func(net.Conn, ConnState) // 错误日志器,不设置默认使用内置logger模块 ErrorLog *log.Logger //原子操做,是否保持长链接 disableKeepAlives int32 // accessed atomically. //原子操做,服务要关闭了 inShutdown int32 // accessed atomically (non-zero means we're in Shutdown) // https相关操做 用于初始化 nextProtoOnce sync.Once // guards setupHTTP2_* init nextProtoErr error // result of http2.ConfigureServer if used // 互斥锁 保证资源的安全 mu sync.Mutex // 服务套接字表,监听socket表 listeners map[*net.Listener]struct{} // 存活的客户端连接表 activeConn map[*conn]struct{} //用于通知服务关闭了 doneChan chan struct{} // 注册服务器关闭执行的一些行为 onShutdown []func() }
注意:通常建立server只须要Addr与handler便可app
ListenAndServe阅读socket
监听并启动服务tcp
func (srv *Server) ListenAndServe() error { // 判断服务器是否是已经关闭了 if srv.shuttingDown() { return ErrServerClosed } // 获取要绑定监听的地址 addr := srv.Addr if addr == "" { addr = ":http" } // 建立用于监监听socket连接 ln, err := net.Listen("tcp", addr) if err != nil { return err } // tcpKeepAliveListener 设置监听超时,在accept的时不会一直阻塞 设置一个超时操做 //启动服务 return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) }
srv.Serve源码阅读函数
func (srv *Server) Serve(l net.Listener) error { // 测试用的钩子函数,其余时候没有用的 if fn := testHookServerServe; fn != nil { fn(srv, l) // call hook with unwrapped listener } // sync.once 建立一个once对象,用于防止屡次关闭连接 l = &onceCloseListener{Listener: l} // 结束的时候关闭监听socket defer l.Close() // 设置http2相关的设置 if err := srv.setupHTTP2_Serve(); err != nil { return err } // 把监听socket添加监听表 if !srv.trackListener(&l, true) { return ErrServerClosed } // 结束的时候从监听表删除 defer srv.trackListener(&l, false) // 设置临时过时时间,当accept发生 错误的时候等待一段时间 var tempDelay time.Duration // how long to sleep on accept failure // 设置context 主要用于取消任务 baseCtx := context.Background() // base is always background, per Issue 16220 // 注意ctx把server自己传递进去了,用于传递 ctx := context.WithValue(baseCtx, ServerContextKey, srv) // 循环监听客户端到来 for { // accept 阻塞等待客户单到来 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 tempDelay = 0 // 建立server链接,server链接包含了与客户端通信的socket以及server相关的信息 c := srv.newConn(rw) // 更新连接状态 c.setState(c.rwc, StateNew) // before Serve can return // 启动goroutine处理socket go c.serve(ctx) } }
server conn结构体阅读post
// 服务端连接结构体 type conn struct { // 连接绑定服务 server *Server // 用于取消任务的ctxFunc cancelCtx context.CancelFunc // socket 通信用的底层socket rwc net.Conn // 客户端地址127.0.0.0:5678 remoteAddr string // tls 状态 tlsState *tls.ConnectionState // werr is set to the first write error to rwc. // 第一次写出现错误的时候设置 werr error // r is bufr's read source. // 用于读取请求的对象,主要用于读取数据的 r *connReader // bufr reads from r. // r读取的数据存储buf bufr *bufio.Reader // bufw writes to checkConnErrorWriter{c}, which populates werr on error. // 写buf bufw *bufio.Writer // lastMethod is the method of the most recent request // on this connection, if any. // 最后一次请求,方法 是post仍是其余等 lastMethod string // 当前的请求 curReq atomic.Value // of *response (which has a Request in it) // 当前cnn状态 curState struct{ atomic uint64 } // packed (unixtime<<8|uint8(ConnState)) //保护hijackedv mu sync.Mutex // hijackedv is whether this connection has been hijacked //表示是否支持用户劫持连接【主要用于切换协议的】 hijackedv bool }