2015-07-26 12 views
6

Bir sunucu şöyle başladığınızı düşünelim? :0, OS tarafından rastgele bir geçici bağlantı noktası seçmek için tasarlanmıştır, ancak hangisinin seçildiğini bilmem gerekiyor.Nasıl olsun adres

NOT: Ben srv.ListenAndServe() kullanmak istediğim iyi bir varsayılan (ama unexported) dinleyicisi beri, kendi dinleyici oluşturmak ve srv.Listen(ln) kullanmaktercih ediyorum.

cevap

2

Ben kendi dinleyici oluşturmak ve srv.Listen (ln) kullanmamayı tercih ediyorum, srv.ListenAndServe() kullanmak istediğim iyi bir varsayılan (ama unexported) dinleyicisi beri.

Neden değil? ListenAndServe() kendini uygulamak için son derece basittir. Bunu kendiniz için read the source code edebilirsiniz:

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

cevap size istediğiniz bilgiye veren) (kendi ListenAndServe yazma kullanmanız gerekecektir olmasıdır. Ancak, düşündüğünüzden çok daha kolay. Her şey 20 satırdan fazla değil (tcpKeepAliveListener ile hayatta kalmak istediğinizi varsayarak).

+0

Benim tercihi sadece tercihlerin, ben 'srv.Listen()' rota gitmek zor değil farkındayım. Sorunu önlediğin için, aynı zamanda port numarasını elde etmenin bir yolunu da anlayamıyorsun. – chowey

+2

Doğru, aslında kendi dinleyicinizi yaratmaktan çok daha kötü şeyler yapmak için bunu yapmak mümkün değil. ListenAndServe, bir kolaylık işlevi anlamına gelir. Bu tür işlevlerin çoğunda olduğu gibi, ikincisi de özel bir şeye ihtiyacınız var, daha düşük bir seviye işlevi kullanmanız gerekir. –

+3

Bu durumun aktarılmamış "tcpKeepAliveListener" işlevini kullandığını unutmayın, böylece TCP'nin hayatta kalmasını istiyorsanız [ayrıca bu kaynağı kopyalamanız gerekir] (https://golang.org/src/net/http/server.go?s= 51082: 51123 # L1967) şükürler olsun ki sadece bir düzine sıradan kod satırı ama bunu yapmak için biraz daha sinir bozucu hale getiriyor. –

0

Sunucu adresini yapılandırmadan önce ücretsiz bir bağlantı noktası seçebilirsiniz. Ücretsiz bir bağlantı noktası elde etmenin daha basit yolu bir dinleyici oluşturmaktır, böylece Stephen önerisini takip ederek aynı sonucu elde edebilirsiniz. İşte tam örnek

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 
} 

https://play.golang.org/p/bG4OpmQbz9s

+0

İşletim sistemi bu bağlantı noktasını o sırada başka bir işleme atarsa ​​ne olur? – chowey

+0

Bu durumda sunucuyu başlatırken bir hatayla karşılaşırsınız, böylece hatanın olup olmadığını sınamanız ve işlemi tekrarlamanız gerekir. GetFreePort yöntemini tekrar çağırıp başka bir bağlantı noktası seçin ve sunucuyu yeniden başlatın. –