port 0, WTF?
Posted on
我们都知道 TCP
或者 UDP
的端口号可以从0一直到65535,而0到1023端口则被称为熟知端口,是系统保留使用的端口号,0号端口在 TCP/IP
中也属于保留端口号,但它并不可以在一般的 TCP
或者 UDP
通信中使用。
但是,如果0号端口不能被使用的话,那它又有什么用呢,简单来讲,就是如果程序监听了0号端口,那么它就会触发操作系统自动去寻找在0到65535这个范围内可以使用的端口号(即未被其他程序占用),这样就相当于动态分配一个端口号了,和 DHCP
协议有着异曲同工之妙,不过 DHCP
是用于动态分配IP地址,而0号端口则用于动态分配端口号,而且两者的工作原理也不同。
所以,如果想要得到一个动态的端口号,我们只要让程序监听0号端口就可以了,即 net.Listen("tcp", "127.0.0.1:0")
,下面给出一个获取动态端口号的示例代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package main
import ( "net" "strconv" )
func GetFreePort() (port int, err error) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { return 0, err } defer listener.Close() addr := listener.Addr().String() _, portString, err := net.SplitHostPort(addr) if err != nil { return 0, err } return strconv.Atoi(portString) }
func main() { port, err := GetFreePort() if err != nil { fmt.Println(err) return }
fmt.Println(port) }
|