web-dev-qa-db-fra.com

Comment utiliser le prochain port disponible dans http.ListenAndServe

J'ai écrit un simple serveur Web pour écouter sur le port 8080. Mais je ne veux pas utiliser de numéro de port codé en dur. Ce que je veux, c'est que mon serveur écoute sur n'importe quel port disponible. Et je veux savoir sur quel numéro de port mon serveur web écoute.

Mon code est donné ci-dessous:

package main

import (
    "net/http"
)

func main() {       
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)

}
18
Raja Hammad Farooq

Vous pouvez utiliser le port 0 Pour indiquer que vous ne spécifiez pas de port exact mais que vous voulez un port libre et disponible sélectionné par le système:

http.ListenAndServe(":0", nil)

Le problème est que vous ne pourrez pas savoir quel port a été attribué. Vous devez donc créer vous-même le net.Listener (en utilisant la fonction net.Listen() ) et le transmettre manuellement à 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))

Exemple de sortie:

Using port: 42039

Comme vous pouvez le voir, vous pouvez accéder au port affecté à partir de net.Listener, À partir de son adresse net.Addr (acquise par sa méthode Addr()). net.Addr Ne donne pas directement accès au port, mais puisque nous avons créé le net.Listener En utilisant le flux réseau tcp, le net.Addr Sera de type dynamique - *net.TCPAddr (que nous pouvons acquérir avec un type assertion ), qui est une structure et a un champ Port int.

Notez que si vous n'avez pas besoin du port dans votre application (par exemple, vous voulez juste l'afficher pour vous-même), vous n'avez pas besoin de l'assertion de type, vous pouvez simplement imprimer listener.Addr() (qui contiendra le port à la fin):

fmt.Println("Address:", listener.Addr())

Exemple de sortie:

Address: [::]:42039

N'oubliez pas non plus de gérer les erreurs retournées (http.ListenAndServe() dans ce cas). Dans mon exemple, je l'ai simplement passé à panic() parce que http.LitenAndServe() et http.Serve() se bloquent si tout se passe bien (donc ils ne reviennent que s'il y a une erreur, à laquelle je passe panic()).

44
icza