如何在Golang中实现基于TCP的实时聊天系统_Golang TCP聊天系统开发实战-Golang

net.Conn 不能直接复用在多个 goroutine 中读写,因其底层读写共享缓冲与状态机,并发调用易导致 io.ErrUnexpectedEOF 或静默丢包;正确做法是读写分离并加锁串行化写操作。

为什么 net.Conn 不能直接复用在多个 goroutine 中读写

很多初学者会把同一个 net.Conn 同时交给两个 goroutine:一个负责 Read,一个负责 Write。这看似合理,但 TCP 连接本身不是线程安全的——Read 和 Write 共享底层缓冲与状态机,一旦并发调用,可能触发 io.ErrUnexpectedEOF 或静默丢包。

正确做法是:每个连接启动两个明确分工的 goroutine,且用互斥控制写操作(读可独立,写需排队):

// 示例:写入前加锁
var mu sync.Mutex
go func() {
    scanner := bufio.NewScanner(conn)
    for scanner.Scan() {
        msg := scanner.Text()
        mu.Lock()
        conn.Write([]byte("echo: " + msg + "\n"))
        mu.Unlock()
    }
}()
  • 读 goroutine 可以无锁运行,但别让它阻塞在 Read 上太久;建议用 SetReadDeadline 防僵死
  • 写操作必须串行化,否则可能错乱或 panic;用 sync.Mutex 最轻量,chan []byte 更适合高吞吐场景
  • 不要在 handler 里直接 conn.Close(),应通知读/写 goroutine 自行退出,再统一关闭

如何避免客户端断连后服务器 goroutine 泄漏

常见错误是只监听 conn.Read 返回 io.EOF 就结束,却没处理网络中断、超时、RST 等情况,导致 goroutine 卡在 Read 或 Write 上不退出。

关键要结合连接生命周期管理:

conn.SetReadDeadline(time.Now().Add(30 * time.Second))
n, err := conn.Read(buf)
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
    // 主动断开闲置连接
    conn.Close()
    return
}
if err == io.EOF || strings.Contains(err.Error(), "broken pipe") {
    conn.Close()
    return
}
  • 每次读/写前都调用 SetReadDeadline / SetWriteDeadline,值随业务逻辑动态更新(比如心跳间隔)
  • 检查 err 时不能只判 io.EOF,还要覆盖 "use of closed network connection"、"broken pipe"、"connection reset by peer"
  • 为每个连接配一个 context.WithCancel,当检测到异常时调用 cancel(),让所有关联 goroutine 快速退出

怎么给每个 TCP 连接分配唯一 ID 并支持广播

Go 没有内置连接 ID,靠 conn.RemoteAddr().String() 不可靠(NAT 后端地址重复),也不能用指针(GC 可能移动)。必须自己生成并维护映射。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 如何在Golang中实现基于TCP的实时聊天系统_Golang TCP聊天系统开发实战-Golang
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4028973+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4028973+
  • 本周更新: 0+
  • 最后更新: 2026-03-16