0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Go】http.ListenAndServe と server.ListenAndServe の違いについて

Last updated at Posted at 2020-08-22

※注意: この記事ははあくまで個人学習用に整理しただけの記事で、内容としては不完全なものになります。読んでも参考にならない可能性が高いです。

http.ListenAndServe と server.ListenAndServe の違い

http.ListenAndServe 使用例

func main() {
    http.Handle("/", &templateHandler{filename: "index.html"})

    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

server.ListenAndServe() 使用例

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", index)
    server := &http.Server{
        Addr:           config.Address,
        Handler:        mux,
        ReadTimeout:    time.Duration(config.ReadTimeout * int64(time.Second)),
        WriteTimeout:   time.Duration(config.WriteTimeout * int64(time.Second)),
        MaxHeaderBytes: 1 << 20,
    }
    server.ListenAndServe()
}

http パッケージの Server struct を確認
https://golang.org/src/net/http/server.go?h=ListenAndServe#L2520

type Server struct {
	Addr			string
	Handler			Handler // handler to invoke, http.DefaultServeMux if nil
	TLSConfig		*tls.Config
	ReadTimeout		time.Duration
	ReadHeaderTimeout	time.Duration
	WriteTimeout		time.Duration
	IdleTimeout		time.Duration
	MaxHeaderBytes		int
	TLSNextProto		map[string]func(*Server, *tls.Conn, Handler)
	ConnState		func(net.Conn, ConnState)
	ErrorLog		*log.Logger
	BaseContext		func(net.Listener) context.Context
	ConnContext		func(ctx context.Context, c net.Conn) context.Context
	inShutdown		atomicBool
	disableKeepAlives	int32
	nextProtoOnce		sync.Once
	nextProtoErr		error
	mu			sync.Mutex
	listeners		map[*net.Listener]struct{}
	activeConn		map[*conn]struct{}
	doneChan		chan struct{}
	onShutdown		[]func()
}

server struct の ListenAndServe method を確認すると

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)
}

上記のようになっており、特に仮引数は受け取らない。

続いて http ListenAndServe 関数を確認

func ListenAndServe(addr string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}

こちらは addr 文字列と handler を仮引数で受け取るようになっている。
関数内部で Server struct のポインタで初期化し、server.ListenAndServe() を実行している。

つまり、http.ListenAndServe(":8080", nil) で実行する場合、addr と handler しか指定することができない。また、その際に、マルチプレクサも指定できない為、DefaultServeMux が使用されるという仕組みのようだ。

自分の中の結論としては、

  • addr と handler のみを指定したい場合は http.ListenAndServe を使用
  • addr と handler 以外も指定したい場合は server.ListenAndServe を使用

という理解になった。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?