How to use next available port in http.ListenAndServe
You may use port 0
to indicate you're not specifying an exact port but you want a free, available port selected by the system:
http.ListenAndServe(":0", nil)
The problem with this is that you won't be able to find out what port was assigned. So you need to create the net.Listener
yourself (using the net.Listen()
function), and manually pass it to http.Serve()
:
listener, err := net.Listen("tcp", ":0")
if err != nil {
panic(err)
}
fmt.Println("Using port:", listener.Addr().(*net.TCPAddr).Port)
panic(http.Serve(listener, nil))
Example output:
Using port: 42039
As you can see, you can access the assigned port from the net.Listener
, from its net.Addr
address (acquired by its Addr()
method). net.Addr
does not directly give access to the port, but since we created the net.Listener
using tcp
network stream, the net.Addr
will be of dynamic type *net.TCPAddr
(which we can acquire with a type assertion), which is a struct and has a field Port int
.
Note that if you don't need the port in your application (e.g. you just want to display it for yourself), you don't need the type assertion, you can just print listener.Addr()
(which will contain the port at the end):
fmt.Println("Address:", listener.Addr())
Example output:
Address: [::]:42039
Also don't forget to handle returned errors (http.ListenAndServe()
in this case). In my example I simply passed it to panic()
because http.LitenAndServe()
and http.Serve()
block if everything goes well (so they only return if there's an error, which I pass to panic()
).
I landed on this page because I wanted to start a new server on a random port for testing purposes. I later learned about the httptest
package, https://golang.org/pkg/net/http/httptest/ , which does a much better job of managing temporary HTTP server for testing.