Go source code analysis-How HTTP. listenandserve () Works

Source: Internet
Author: User

Go provides excellent support for the compilation of web servers. The standard library provides net/HTTP packages to facilitate the compilation of servers. Many tutorials and books will teach beginners how to write a simple hello World server using HTTP packets when writing Web servers using go. The examples are similar to the following:

// This is the simplest Hello World server implemented with go. package mainimport "net/HTTP" func main () {HTTP. handlefunc ("/", func (w http. responsewriter, R * HTTP. request) {W. write ([] Byte ('Hello World')}) HTTP. listenandserve (": 3000", nil) // <-how does listenandserve work today}

We can see that the code is really short and only a few lines are needed. What we want to analyze today is HTTP. listenandserve (). Let's see what has been done here.


First, all the dependencies used by HTTP. listenandserve are in the go source code./Src/PKG/NET/HTTP/server. GoIn the file, open it and you will find that the Code on this page is very long, there are more than 2000 lines, we press Ctrl + F to directly find the part we are interested in, and find the part about 1770 lines found HTTP. listenandserve definition:

Func listenandserve (ADDR string, Handler handler) error {// create a server struct, call the listenandserver method of the struct, and return server :=& server {ADDR: ADDR, Handler: handler} return server. listenandserve ()}
From this function, we can see that HTTP is called. what actually works after listenandserve is the server structure lisntenandserve method, which is used for HTTP. the parameters passed by listenandserve are only used to create a server struct instance. The server struct is defined as follows:

Type server struct {ADDR string // server IP address and port information handler // readtimeout time of the route multiplexing of the request processing function. duration writetimeout time. durationmaxheaderbytes int tlsconfig * TLS. config tlsnextproto map [String] func (* server, * TLS. conn, Handler) connstate func (net. conn, connstate) errorlog * log. loggerdisablekeepalives int32}
If we do not pass specific parameters to HTTP. listenandserve, it will automatically use ": http" (equivalent to ": 80") and defaulservemux as parameters to create server struct instances.

Next, let's take a look at what has been done in server. listenandserve. You can find the definition around 1675 lines:

Func (SRV * server) listenandserve () error {ADDR: = srv. addrif ADDR = "" {ADDR = ": http" // if no server address is specified, ": http" is used as the address information by default.} ln, err: = net. listen ("TCP", ADDR) // a TCP listener is created here and then used to receive the client connection request if Err! = Nil {return err} return srv. Serve (tcpkeepalivelistener {ln. (* Net. tcplistener)}) // call the server. Serve () function and return}
As you can see, server. listenandserve creates a server listener, and then transmits it to the server. Serve () method and calls server. Serve () when it returns ().


Continue to analyze server. Serve, which is defined at around 1690 rows:

Func (SRV * server) serve (L net. listener) error {defer L. close () var tempdelay time. duration // This cycle is the master cycle of the server. The listener receives requests from the client and establishes a connection. // then, create a routine for each connection and execute C. serve (), this C. the specific service processes for {RW, E: = L. accept () If e! = Nil {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 = 0C, err: = srv. newconn (RW) If Err! = Nil {continue} C. setstate (C. RWC, statenew) // before serve can returngo C. serve () // <-here we create a routine for each established connection for service }}

Let's take a look at how the service is performed in the conn. Serve (). The Code is near line 1 and only the main part of the code is shown below:

Func (C * conn) serve () {origconn: = C. RWC // copy it before it's set nil on close or hijack // some processing related to latency release and TLS is done here... // The previous part can be ignored. Here is the main loop for {W, err: = C. readrequest () // read the client request //... serverhandler {C. server }. servehttp (W, W. REQ) // process the request here if C. hijacked () {return} W. finishrequest () If W. closeafterreply {If W. requestbodylimithit {C. closewriteandwait ()} break} C. setstate (C. RWC, stateidle )}}


After a thorough analysis, the HTTP. listenandserve workflow is almost clear. We can summarize it into a flowchart:





If reprinted please indicate the source: http://blog.csdn.net/gophers


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.