Go 的 net.Listen + Accept 是创建 TCP 服务器最直接、最可控的方式,需手动处理连接生命周期、错误边界、超时控制、资源清理及缓冲区复用策略。
Go 的 net.Listen + Accept 是创建 TCP 服务器最直接、最可控的方式,无需框架也能稳定支撑万级并发,但必须手动处理连接生命周期和错误边界。
用 net.Listen 启动监听时常见绑定失败原因
启动失败通常不是代码写错,而是端口被占、权限不足或地址不合法:
-
listen tcp :8080: bind: address already in use:先用lsof -i :8080(macOS/Linux)或netstat -ano | findstr :8080(Windows)查 PID,再kill -9 [PID] -
listen tcp :80: bind: permission denied:Linux/macOS 下非 root 用户不能绑定 1–1023 端口,改用:8080或加sudo -
listen tcp 127.0.0.1:8080: listen: invalid argument:传了非法地址字符串,确保是"localhost:8080"或":8080",不要带空格或协议前缀
Accept 循环里必须显式关闭 conn 并处理超时
不关连接会导致文件描述符耗尽;不设超时会让恶意客户端长期占着 goroutine:
- 每次
Accept返回的conn必须在 goroutine 内部用defer conn.Close()关闭 - 用
conn.SetDeadline或SetReadDeadline/SetWriteDeadline设硬性截止时间,例如conn.SetReadDeadline(time.Now().Add(30 * time.Second)) - 不要依赖
http.Server那套机制——纯 TCP 没有自动 keep-alive 或 idle timeout,全靠自己控
并发模型选 go handle(conn) 还是 sync.Pool 复用 buffer?
对大多数业务场景,直接起 goroutine 更简单可靠;sync.Pool 只在高频小包、GC 压力大时才值得引入: