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

如何实现TCP客户端持续接收TCP服务器的数据?现有代码异常问题咨询

问题分析与解决方案

你的TCP客户端只能接收一次数据,核心问题出在服务器的处理逻辑上,客户端代码基本没问题,但也有小细节可以优化。

服务器端的核心问题

当前的handleRequest函数只完成了一次消息交互就直接关闭了连接:

  • 它读取一次客户端数据(哪怕客户端没发送任何内容),然后读取一次控制台输入发送给客户端,紧接着就调用conn.Close()断开连接。这就导致每个TCP连接只能传输一次数据,客户端自然只能收到一次消息,之后连接断开,客户端的循环就会持续打印错误。
  • 另外,服务器发送消息时没有添加换行符\n,而客户端是用bufio.Reader.ReadBytes('\n')来读取数据的——这会导致客户端即使收到了消息,也会一直等待换行符,直到连接关闭才会返回读取结果。

修改后的服务器代码

要实现持续通信,服务器需要在一个连接内保持循环,持续处理消息,直到连接主动断开或出现错误。同时要记得发送消息时加上换行符,匹配客户端的读取逻辑:

import (
    "fmt"
    "io"
    "net"
)

// Handles incoming requests.
func handleRequest(conn net.Conn) {
    defer conn.Close() // 把Close放到defer,确保连接最终会关闭
    buf := make([]byte, 1024)
    for {
        // 读取客户端数据(如果需要双向通信的话)
        n, err := conn.Read(buf)
        if err != nil {
            if err != io.EOF {
                fmt.Println("Error reading:", err.Error())
            }
            break // 客户端断开或出错,退出循环
        }
        if n > 0 {
            fmt.Println("Received from client:", string(buf[:n]))
        }

        // 读取控制台输入并发送给客户端
        var msg string
        fmt.Scanln(&msg)
        // 加上换行符,让客户端的ReadBytes能正确识别结束
        _, err = conn.Write([]byte(msg + "\n"))
        if err != nil {
            fmt.Println("Error writing:", err.Error())
            break
        }
    }
    fmt.Println("Connection closed")
}

func main() {
    listener, err := net.Listen("tcp", ":3333")
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        return
    }
    defer listener.Close()
    fmt.Println("Server listening on :3333")
    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("Error accepting:", err.Error())
            continue
        }
        go handleRequest(conn) // 用goroutine处理每个连接,支持多客户端
    }
}

客户端代码的优化

客户端的逻辑已经能持续读取,但错误处理可以更完善,避免连接断开后无限打印错误:

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "time"
)

func main() {
    tcpAddr := "localhost:3333"
    conn, err := net.DialTimeout("tcp", tcpAddr, time.Second*7)
    if err != nil {
        log.Println("Failed to connect:", err)
        return // 连接失败直接退出
    }
    defer conn.Close()
    // conn.Write([]byte("Hello World")) // 如果需要发送初始消息可以打开
    connBuf := bufio.NewReader(conn)
    for {
        bytes, err := connBuf.ReadBytes('\n')
        if err != nil {
            log.Println("Receive Error:", err)
            break // 出错后退出循环,避免无限打印
        }
        if len(bytes) > 0 {
            fmt.Println("Received:", string(bytes))
        }
        time.Sleep(time.Second * 2)
    }
}

测试效果

现在启动服务器后,每次在控制台输入内容并回车,客户端都会收到对应的消息(因为服务器添加了换行符,客户端能正确读取),直到你关闭服务器或者客户端,连接才会断开。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:27:40