net 标准库是 Go 底层网络通信基石,提供 TCP/UDP 连接、IP 解析、Listener/Conn 等原语;http 等上层包依赖其完成端口监听、连接收发与字节读写。

net 标准库是 Go 语言处理底层网络通信的基石,它不直接封装 HTTP 或 DNS 协议逻辑,而是提供 TCP/UDP 连接、IP 地址解析、监听器(Listener)、连接(Conn)等原语,让 http、rpc、net/smtp 等上层包得以构建。
为什么你写的 HTTP 服务其实在用 net 库
当你调用 http.ListenAndServe(":8080", nil),表面看是 net/http 在工作,但背后真正打开端口、接受连接、读写字节流的,全是 net 包里的 net.Listen("tcp", ":8080") 和 ln.Accept()。HTTP Server 只是把 net.Conn 接过来,再按 HTTP 协议解析字节——没 net,http 就是空中楼阁。
-
net.Listener是接口,net.TCPListener是具体实现;启动服务时,http.Server.Serve(ln)实际在循环调用ln.Accept() - 每个请求对应一个
net.Conn,它实现了io.ReadWriteCloser,所以你能用conn.Read()拿到原始字节 - 常见错误:忘记
defer conn.Close()→ 连接泄漏;或对已关闭的conn再读写 → 报use of closed network connection
IP 地址和域名解析必须靠 net.LookupXXX
想把 "google.com" 变成 "142.250.191.46"?不能靠字符串拼接,得用 net.LookupHost() 或更细粒度的 net.LookupIP()。它们返回的是 []net.IP,不是字符串——这是很多新手卡住的第一步。
-
net.ParseIP("192.168.1.1")返回net.IP类型,可直接用于net.Dial("tcp", ip.String()+":80") -
net.ParseCIDR("10.0.0.0/8")解析网段,常用于 ACL 判断:用ipNet.Contains(clientIP) - 注意:DNS 解析可能超时或失败,生产环境必须设 context 控制:
net.DefaultResolver.LookupHost(ctx, "example.com")
TCP vs UDP:连不上?先看协议类型是否匹配
net.Dial("tcp", ...) 和 net.Dial("udp", ...) 完全不同:TCP 是有状态连接,需 conn.Close();UDP 是无连接数据报,net.Conn 只是方便封装,实际用 WriteTo()/ReadFrom() 更直接。
立即学习“go语言免费学习笔记(深入)”;
- TCP 场景:长连接服务(如 Redis 客户端)、需要可靠传输的 RPC
- UDP 场景:DNS 查询、日志上报、实时音视频——别用
net.DialUDP建“连接”,而应直接用net.ListenUDP+conn.WriteTo() - 常见坑:
net.Dial("udp", "127.0.0.1:53")不会报错,但发不出去——因为 UDP 不建立连接,错误只在第一次WriteTo时暴露(比如目标端口无服务)
net 库的“简单”是假象:它把 socket、bind、listen、accept、read/write 全部收敛成几个接口,但每个方法背后都直面操作系统行为。比如 net.Listen("tcp", ":0") 让内核自动选空闲端口,返回的 addr.Port 才是真实值——这种细节,不查文档、不写测试,上线就翻车。











