跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何在Golang中使用net包进行网络编程_Golang网络编程入门实战

Go net包开箱即用但需手动处理超时、并发、错误和连接生命周期;TCP服务需goroutine并发处理conn并显式设Deadline;Dial应配超时避免卡顿;UDP无连接,ListenUDP可收发任意地址,DialUDP绑定远端;安全关闭需WaitGroup等待活跃连接结束。 Go 的
net
包开箱即用,适合快速构建 TCP/UDP 服务和客户端,但直接调用底层接口容易忽略连接生命周期、超时控制和错误处理细节。 如何用
net.Listen
启动一个基础 TCP 服务
net.Listen
返回
net.Listener
,它本身不处理连接逻辑,只负责接受新连接。常见错误是忘记用
defer ln.Close()
或在循环中未对每个
conn
启动 goroutine 导致阻塞。 监听地址格式必须带端口,如
"localhost:8080"
或
":8080"
;写成
"8080"
会报
"listen tcp: address 8080: missing port in address"
建议显式设置读写超时:在
conn
上调用
SetReadDeadline
和
SetWriteDeadline
,否则空闲连接可能长期滞留 典型结构是
for { conn, err := ln.Accept(); go handle(conn) }
,不加
go
就变成串行处理,无法并发 为什么
net.Dial
连接失败后常卡住几秒 默认情况下
net.Dial
没有超时,DNS 解析失败或目标端口无响应时会等系统默认 timeout(Linux 通常 30 秒)。这不是 bug,而是设计上把超时控制权交给使用者。 改用
net.DialTimeout
,例如
net.DialTimeout("tcp", "example.com:80", 5*time.Second)
更推荐用
net.Dialer
配合
Context
:构造
&net.Dialer{Timeout: 3*time.Second, KeepAlive: 30*time.Second}
,再调用
dialer.DialContext(ctx, "tcp", addr)
注意:即使设置了超时,如果 DNS 解析慢(比如 /etc/resolv.conf 配了多个 slow nameserver),仍可能卡在解析阶段 —— 此时需配合
net.Resolver
自定义超时 UDP 编程中
net.ListenUDP
和
net.DialUDP
的关键区别 TCP 是面向连接的,UDP 是无连接的,所以
net.ListenUDP
返回的
*net.UDPConn
可同时收发;而
net.DialUDP
创建的连接“绑定”了远端地址,
WriteToUDP
不能用,只能用
Write
。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”;
ListenUDP
常用于服务器:用
ReadFromUDP
接收任意来源数据,用
WriteToUDP
回复指定地址
DialUDP
更适合客户端场景:比如向 NTP 服务器发请求,之后所有
Write
默认发给同一地址,
Read
只收该地址的响应 UDP 没有内置重传和顺序保证,应用层若需可靠传输,得自己实现序列号、ACK 和重发逻辑 如何安全关闭正在运行的
net.Listener
直接调用
ln.Close()
不会中断已建立的
conn
,但后续
Accept()
会返回
ErrClosed
。真正的难点在于等待已有连接处理完成。 不要在
ln.Close()
后立刻退出程序,否则活跃
conn
可能被强制断开 常用做法是用
sync.WaitGroup
记录活跃连接数:每次
Accept
后
wg.Add(1)
,
handle
结束前
wg.Done()
关闭流程应为:
ln.Close()
→ 启动 goroutine 调用
wg.Wait()
→ 再退出;也可结合
context.WithTimeout
防止无限等待 net 包足够轻量,但也因此把很多责任留给了开发者:超时、重试、连接池、TLS 封装都得自己补全。一个小而完整的网络服务,往往 80% 的代码不在
Listen
或
Dial
,而在围绕它们构建的错误恢复和资源管理逻辑里。

相关文章