Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use next available port in http.ListenAndServe

I wrote a simple web server to listen on port 8080. But I don't want to use a hard coded port number. What I want is that my server listen on any available port. And I want to know that on what port number my web server is listening.

My code is given bellow:

package main  import (     "net/http" )  func main() {            http.HandleFunc("/", handler)     http.ListenAndServe(":8080", nil)  } 
like image 227
Raja Hammad Farooq Avatar asked Apr 15 '17 10:04

Raja Hammad Farooq


People also ask

How do I listen a port in go?

To use a random available port in Golang, you can use :0 . I believe the port 0 would works for another language as well as I tried in python. According to lifewire, port 0 is a non-ephemeral port that works as a wildcard that tells the system to find any available ports particularly in the Unix OS.

What port does Golang use?

Have your Go server running on port 80.


1 Answers

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()).

like image 127
icza Avatar answered Sep 18 '22 22:09

icza