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 压力大时才值得引入:
Destoon B2B网站管理系统是一套完善的B2B(电子商务)行业门户解决方案。系统基于PHP+MySQL开发,采用B/S架构,模板与程序分离,源码开放。模型化的开发思路,可扩展或删除任何功能;创新的缓存技术与数据库设计,可负载千万级别数据容量及访问。 系统特性1、跨平台。支持Linux/Unix/Windows服务器,支持Apache/IIS/Zeus等2、跨浏览器。基于最新Web标准构建,在
立即学习“go语言免费学习笔记(深入)”;
- 每个连接一个 goroutine 是 Go TCP 服务的标准做法,runtime 调度开销极低
- 如果单次读写量小(如 MQTT 心跳、自定义协议头),可复用
[]byte缓冲区:buf := make([]byte, 1024)放 goroutine 栈上即可,不用池 - 只有当出现
runtime: out of memory且 pprof 显示大量[]byte在堆上时,才考虑用sync.Pool管理缓冲区
真正难的是连接断开时的状态清理——比如客户端突然拔网线,Read 可能阻塞数分钟才返回 io.EOF 或超时错误,这时候你得确保所有关联资源(数据库连接、计时器、日志句柄)都一并释放。别只盯着 conn.Close()。









