测试 udp 和 tcp 端口分配的时候重复的几率。新建一个 socket,然后关闭,重复 10000 次。观察重复的端口数量。
go build main.go
$ ./main -network udp -count 10000 > udp.txt
$ sort udp.txt | uniq | wc -l
8447
$ head udp.txt
127.0.0.1:46505
127.0.0.1:35658
127.0.0.1:47554
127.0.0.1:43733
127.0.0.1:42153
127.0.0.1:49265
127.0.0.1:42846
127.0.0.1:49819
127.0.0.1:33297
127.0.0.1:32814
udp 因为分配的端口没有状态,所以重复的几率比较高。10000 次重复出现了 1500 多个重复。
$ nc -l -k 9090 &
$ ./main -network tcp -count 10000 > tcp.txt
$ sort tcp.txt | uniq | wc -l
10000
$ netstat -an | grep 9090 | grep TIME_WAIT | wc -l # 马上执行
10000
$ ./main -network tcp -count 40000 > tcp.txt
2019/11/25 17:45:41 dial tcp 127.0.0.1:9090: connect: cannot assign requested address
$ sort tcp.txt | uniq | wc -l
28233
tcp 测试没有发现重复,一个可能的解释是 tcp 主动关闭连接以后,连接处于 TIME_WAIT 状态, 系统会选择没有状态的端口。
默认情况下系统不会重用 TIME_WAIT 状态的端口,而是直接报错了。