Golang http IPv4/IPv6 服务
🕐 Tue, 09 Apr 2019 by GolangNote
Golang 的网络服务,如果不指定IPv4 或 IPv6,如果VPS 同时支持 IPv4 和 IPv6,net.Listen()
只会监听 IPv6 地址。但这不影响客户端使用 IPv4 地址来访问。
如下使用 netstat -lnt
来查看端口监听情况:
# 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
来选择,如:
http.ListenAndServe(":8083", nil) // tcp
http.ListenAndServe("[2604:180:3:dd3::276e]:8083", nil) // 具体指定 tcp6
如果觉得具体指定 IPv6地址太麻烦,可以重构 ListenAndServe
函数,会用到 net.Listen
函数, 可以在该函数里指定 network
,可选 tcp
、tcp4
、tcp6
。
network 可选参数:
"tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket"
常用:
tcp 自动适配,优先IPv6
tcp4 仅使用IPv4
tcp6 仅使用IPv6
重构的 ListenAndServe
函数示例:
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 服务:
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 (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。如果你有任何问题可以在下面 留言
Be the first to comment!
Relative Articles
Recent Go Articles
- Golang 把cookie 字符串解析为cookie 结构
- Golang 计算字符串中包含某个或某些字符集的个数
- 使用Golang 对文件增删写读操作备忘
- Go Modules 使用备忘
- 使用Golang 简单删除图片exif 信息
- 谷歌翻译的 golang 库推荐
- Go 1.13.2 与1.13.3 紧急更新
- golang 人脸检测识别库
- Go build 错误 “stackcheck redeclared in this block previous declaration”的解决方法
- Golang phantomjs 动态代理实现
- Golang chrome debug protocol 库推荐
- Golang 随机打乱数组/Slice
- Golang sync.WaitGroup 的 Wait 超时处理
- Golang实现简单的Socks5代理
- Golang 用snappy + Base64 简单压缩加密进行网络传输
- Golang http IPv4/IPv6 服务
- golang 全角半角相互转换
- 在自己的网站部署TLS 1.3
- Golang 实现/打印菜单树
- Golang telegram 机器人小试
Top Go Articles
- 用golang 标准库regexp 验证用户名和密码的合法性
- Golang http IPv4/IPv6 服务
- mismatched types time.Duration and int
- golang 用gzip 压缩、解压缩字符串
- golang 简单全局计数器实现
- Golang sync.WaitGroup 的 Wait 超时处理
- Golang telegram 机器人小试
- Golang 并发控制的两种模式
- go 获取硬盘的可用空间的方法
- iris websocket 自定义信息结构
- golang map 按value 大小排序,降序和升序
- Golang Leveldb 基本使用的例子
- go post 上传文件的例子
- golang 生成良好的唯一ID/uuid库比较
- golang 获取用户真实访问ip 地址
- Golang webview 做桌面应用及跨平台编译
- Golang http.Post 用最小的内存发送大文件
- golang image 智能合并图片
- Golang string 和byte 操作性能比较
- golang 使用crypto/rand 生成随机数