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
相关产品推荐
相关产品推荐

