Windows下端口绑定失败的问题

在Windows下做如下实验

  1. 打开hyper-v
  2. 打开虚拟机平台
  3. 打开WSL2

具体怎么开这里就不详述了,可以自行google

然后在windows环境下,尝试监听1200端口,比如我这里用go 创建 main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
"net/http"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello world")
}

func main() {
http.HandleFunc("/", indexHandler)
err := http.ListenAndServe(":1200", nil)
if err!=nil {
panic(err)
}
}

执行go run main.go 如果你遇到下面的报错,说明你也踩坑了。

1
An attempt was made to access a socket in a way forbidden by its access permissions

这种情况下,当你 netstat -ano|findstr "1200" 却会发现并没有端口冲突。或者你尝试用管理员权限运行此程序也无济于事。

原因

一句话,打开HyperV后,Windows调整了动态端口映射,专门用于HyperV的NAT。

1
2
3
4
5
6
netsh int ipv4 show dynamicport tcp

协议 tcp 动态端口范围
---------------------------------
启动端口 : 1024
端口数 : 13977

默认1024到13977这个段的端口,你去绑定的话,可能会遇到上面的报错。

解决

  1. 关闭Hyper-V
    这个大多数开发人员基本不考虑,WSL2,Docker都是刚需。

  2. 排除端口

    1
    netsh int ipv4 add excludedportrange protocol=tcp startport=1200 numberofports=1

    这个命令会排除从1200开始长度为1的端口段。

结果可以查看

1
2
3
4
5
6
7
8
9
10
11
netsh interface ipv4 show excludedportrange protocol=tcp

协议 tcp 端口排除范围

开始端口 结束端口
---------- --------
1200 1200 *
7890 7890 *
50000 50059 *

* - 管理的端口排除。

我们已经配置成功了。后面就可以正常监听1200端口了