net.Conn连接高速收发数据丢失及JSON解析错误问题咨询
问题根因
代码中最核心的错误是在读取goroutine的循环中每次都新建bufio.Reader实例:
for { netData, err := bufio.NewReader(conClient).ReadString('\n') // 其他逻辑 }
bufio.Reader为了减少系统调用开销,会默认从底层连接预读最多4KB数据到内部缓冲区。每次循环新建reader实例时,上一个reader缓冲区中已经预读到的未处理数据会随实例销毁直接丢失,这就是你遇到payload部分缺失、首部缺失的直接原因。
修复方案
将bufio.Reader的初始化移到循环外部,整个连接生命周期复用同一个reader实例即可:
go func(chnData chan string) { // 全局复用同一个reader reader := bufio.NewReader(conClient) for { netData, err := reader.ReadString('\n') if err != nil { if !strings.Contains(err.Error(), "EOF") { chnLogging <- "Error from client " + conClient.RemoteAddr().String() + ": " + err.Error() } else { chnLogging <- "Client " + conClient.RemoteAddr().String() + " disconnected" } chnCloseConn <- true return } tmTimeout.Stop() tmTimeout.Reset(time.Minute * SERVER_INACTIVITY_TIMEOUT_MINUTES) chnData <- netData } }(chnDataFromClient)
其他潜在问题优化
- 你遇到的
invalid character X after top-level value错误,还可能是单条ReadString读到了多条拼接的JSON payload(TCP底层粘包),建议增加逻辑拆分读到的字符串中所有以\n分隔的内容,逐个处理。 net.Conn的Write操作不支持并发安全,若有其他goroutine同时往同一个连接写数据,会出现数据乱码、拼接的问题,建议对写操作加互斥锁,或统一通过专用的写goroutine处理所有返回数据发送。- 目前直接用
CheckErr(err)处理JSON反序列化错误,遇到非法输入会直接panic,建议改成返回错误并主动关闭异常连接,避免单个客户端异常导致服务整体崩溃。
内容的提问来源于stack exchange,提问作者Bart Silverstrim
相关产品推荐
相关产品推荐

