Golang 的网络服务,如果不指定IPv4 或 IPv6,如果VPS 同时支持 IPv4 和 IPv6,net.Listen()
只会监听 IPv6 地址。但这不影响客户端使用 IPv4 地址来访问。
如下使用 netstat -lnt
来查看端口监听情况:
1
2
3
4
5
6
7
8
9
10
11
# netstat -lnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::25 :::* LISTEN
tcp6 0 0 :::443 :::* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::80 :::* LISTEN
如何在启动网络服务时选择 IPv6?
在高层可以使用 http.ListenAndServe
来选择,如:
1
2
3
http.ListenAndServe(":8083", nil) // tcp
http.ListenAndServe("[2604:180:3:dd3::276e]:8083", nil) // 具体指定 tcp6
如果觉得具体指定 IPv6地址太麻烦,可以重构 ListenAndServe
函数,会用到 net.Listen
函数, 可以在该函数里指定 network
,可选 tcp
、tcp4
、tcp6
。
network 可选参数:
1
2
3
4
5
6
7
8
9
10
11
12
"tcp",
"tcp4" (IPv4-only),
"tcp6" (IPv6-only),
"udp",
"udp4" (IPv4-only),
"udp6" (IPv6-only),
"ip",
"ip4" (IPv4-only),
"ip6" (IPv6-only),
"unix",
"unixgram",
"unixpacket",
常用:
1
2
3
tcp 自动适配,优先IPv6
tcp4 仅使用IPv4
tcp6 仅使用IPv6
重构的 ListenAndServe
函数示例:
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
32
33
34
35
36
37
38
39
40
41
42
43
package main
import (
"fmt"
"net"
"net/http"
)
type helloHandler struct{}
func (h *helloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, world!"))
}
func main() {
var err error
http.Handle("/", &helloHandler{})
//err = http.ListenAndServe(":8083", nil) // IPv4 或 IPv6
//err = http.ListenAndServe("[2604:180:3:dd3::276e]:8083", nil) // 具体指定,仅 IPv6
err = ListenAndServe(":8083", nil) // 重构的 ListenAndServe 函数
if err != nil {
fmt.Println(err)
}
}
//
type tcpKeepAliveListener struct {
*net.TCPListener
}
func ListenAndServe(addr string, handler http.Handler) error {
srv := &http.Server{Addr: addr, Handler: handler}
addr = srv.Addr
if addr == "" {
addr = ":http"
}
ln, err := net.Listen("tcp6", addr) // 仅指定 IPv6
if err != nil {
return err
}
return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
}
客户端可以用下面的命令行检测 IPv6 服务:
1
2
3
curl "http://[2604:180:3:dd3::276e]:8083"
curl -g -6 'http://[2604:180:3:dd3::276e]:8083/'
telnet -6 2604:180:3:dd3::276e 8083
本文网址: https://golangnote.com/topic/256.html 转摘请注明来源