You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang Socket服务器无法接受多客户端连接问题求助

问题分析与修复

你的代码存在两个核心问题,导致无法同时处理多客户端连接:

1. 循环变量捕获错误

goroutine定义时传入了参数c,但内部却使用了外部的conn变量。Go的循环变量在迭代过程中是复用的,后续Accept返回的新连接会覆盖conn的值,最终所有goroutine实际操作的都是最后一个连接,旧连接得不到正确处理,进而引发新连接挂起的异常。

2. 重复创建bufio.Reader

每次循环都新建bufio.NewReader(conn),导致缓冲区无法复用。如果客户端发送的数据未包含换行符,多次创建的Reader会各自读取部分数据,要么引发读取阻塞,要么导致数据丢失,间接打乱了连接处理逻辑。


修复后的代码

package main

import (
    "bufio"
    "log"
    "net"
)

func main() {
    l, err := net.Listen("tcp", ":8081")
    if err != nil {
        log.Fatal(err)
    }
    defer l.Close()
    for {
        conn, err := l.Accept()
        if err != nil {
            log.Printf("Accept error: %+v", err.Error())
            continue // 单个连接出错时不崩溃服务器
        }

        go func(c net.Conn) {
            defer c.Close() // 确保goroutine退出时释放连接资源
            reader := bufio.NewReader(c) // 仅创建一次Reader,复用缓冲区
            for {
                message, err := reader.ReadString('\n')
                if err != nil {
                    log.Printf("Client %s error: %+v", c.RemoteAddr(), err.Error())
                    return
                }
                log.Printf("From %s: %s", c.RemoteAddr(), message)
            }
        }(conn)
    }
}

修复说明

  • 改用goroutine的参数c操作连接,彻底避免循环变量覆盖的问题;
  • 将bufio.NewReader移到循环外部,保证缓冲区复用,读取逻辑一致;
  • 添加defer c.Close(),确保客户端连接断开或处理出错时,及时释放连接资源;
  • 将Accept后的log.Fatal(err)改为log.Printf加continue,避免单个连接的错误导致整个服务器崩溃。

内容的提问来源于stack exchange,提问作者RomCoca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 04:05:22