比如我们经常会有这样的代码开始一个网络端口监听:

err := http.ListenAndServe(listenAddr, nil)
http包中这个函数的实现是:
func ListenAndServe(addr string, handler Handler) error
:= &Server{Addr: addr, Handler: handler}
return
}
server.ListenAndServe() 函数的实现如下:
func (srv *Server) ListenAndServe() error
:=
if addr == ""
":http"
    }
:= net.Listen("tcp", addr)
if e != nil
return
    }
return
}
srv.Serve( 函数的实现如下,注意看到有网络连接产生后 c, err := srv.newConn(rw) ,我们开了一个协程。
func (srv *Server) Serve(l net.Listener) error
defer
    var tempDelay time.Duration // how long to sleep on accept failure
for
:=
if e != nil
if ne, ok := e.(net.Error); ok &&
if tempDelay == 0
5 *
else
*= 2
                }
if max := 1 *
                    tempDelay = max
                }
"http: Accept error: %v; retrying in %v", e, tempDelay)
                time.Sleep(tempDelay)
continue
            }
return
        }
0
if srv.ReadTimeout != 0
            rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))
        }
if srv.WriteTimeout != 0
            rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))
        }
:=
if err != nil
continue
        }
go
    }
    panic("not reached")
}
 
从上面可以看到,每个客户端请求连接,都是开始了一个协程。
每次请求的实体类包含的信息如下:
type conn struct {
    remoteAddr string               // network address of remote side
    server     *Server              // the Server on which the connection arrived
// i/o connection
*io.LimitedReader    // io.LimitReader(rwc)
    buf        *bufio.ReadWriter    // buffered(lr,rwc), reading from bufio->limitReader->rwc
    hijacked   bool                 // connection has been hijacked by handler
*tls.ConnectionState // or nil when not using TLS
byte
}
 
c.serve( 方法包含整个连接从打开到关闭的整个生命周期,即,一个连接是一个协程。
// Serve a new connection.
func (c *conn) serve() {
defer func() {
:= recover()
if err == nil
return
        }
 
var
&buf, "http: panic serving %v: %v\n", c.remoteAddr, err)
        buf.Write(debug.Stack())
        log.Print(buf.String())
 
        if c.rwc !=nil { // may be nil if connection hijacked
            c.rwc.Close()
        }
    }()
 
if tlsConn, ok := c.rwc.(*tls.Conn); ok {
if err := tlsConn.Handshake(); err != nil
close()
return
        }
new(tls.ConnectionState)
*c.tlsState = tlsConn.ConnectionState()
    }
 
for
:=
if err != nil
:= "400 Bad Request"
if err ==
                // Their HTTP client may or may not be
                // able to read this if we're
                // responding to them and hanging up
                // while they're still writing their
                // request.  Undefined behavior.
                msg = "413 Request Entity Too Large"
else if err ==
break // Don't reply
else if neterr, ok := err.(net.Error); ok &&
break // Don't reply
            }
"HTTP/1.1 %s\r\n\r\n", msg)
break
        }
 
        // Expect 100 Continue support
:=
if
if req.ProtoAtLeast(1, 1) {
                // Wrap the Body reader with one that replies on the connection
&expectContinueReader{readCloser: req.Body, resp: w}
            }
if req.ContentLength == 0
"Connection", "close")
                w.WriteHeader(StatusBadRequest)
                w.finishRequest()
break
            }
"Expect")
else if req.Header.Get("Expect") != ""
            // TODO(bradfitz): let ServeHTTP handlers handle
            // requests with non-standard expectation[s]? Seems
            // theoretical at best, and doesn't fit into the
            // current ServeHTTP model anyway.  We'd need to
            // make the ResponseWriter an optional
            // "ExpectReplier" interface or something.
//
            // For now we'll just obey RFC 2616 14.20 which says
            // "If a server receives a request containing an
            // Expect field that includes an expectation-
            // extension that it does not support, it MUST
            // respond with a 417 (Expectation Failed) status."
"Connection", "close")
            w.WriteHeader(StatusExpectationFailed)
            w.finishRequest()
break
        }
 
:=
if handler == nil
            handler = DefaultServeMux
        }
 
        // HTTP cannot have multiple simultaneous active requests.[*]
        // Until the server replies to this request, it can't read another,
        // so we might as well run the handler in this goroutine.
        // [*] Not strictly true: HTTP pipelining.  We could let them all process
        // in parallel even if their responses need to be serialized.
        handler.ServeHTTP(w, w.req)
if
return
        }
        w.finishRequest()
if
break
        }
    }
close()
}