如何实现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
相关产品推荐
相关产品推荐

