How to get the address for http.ListenAndServe

Let's say I run a server like this:

srv := http.Server{ Addr: ":0", Handler: http.FileServer(http.Dir(".")), } go srv.ListenAndServe() log.Printf("Listening on ???") 

How can I determine which port was selected? :0 is for random OS ephemeral port selection, but I need to know which one was selected.

NOTE. . I would prefer not to create my own listener and use srv.Listen(ln) , since srv.ListenAndServe() has a nice standard (but not exported) listener that I want to use.

+6
source share
2 answers

I would prefer not to create my own listener and use srv.Listen (ln), since srv.ListenAndServe () has a nice standard (but not exported) listener that I want to use.

Why not? ListenAndServe () is extremely easy to implement. You can read the source code for yourself:

 func (srv *Server) ListenAndServe() error { addr := srv.Addr if addr == "" { addr = ":http" } ln, err := net.Listen("tcp", addr) if err != nil { return err } return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) } 

The answer is that you will need to write your own ListenAndServe (), which will give you the necessary information. This is much easier than you think. All this is no more than 20 lines (if you want to install keep-alives with tcpKeepAliveListener ).

+2
source

You can select a free port before setting the server address. An easier way to get a free port is to create a listener so that you can get the same result as Stephen's suggestion.

 func GetFreePort() (int, error) { ln, err := net.Listen("tcp", ":0") if err != nil { return 0, err } err = ln.Close() if err != nil { return 0, err } return ln.Addr().(*net.TCPAddr).Port, nil } 

Here is a complete example https://play.golang.org/p/bG4OpmQbz9s

0
source

All Articles