我是个新手,我正在尝试用go构建一个简单的TCP服务器和客户端。客户端向服务器发送一条消息"hello from client“,并等待服务器响应消息"Successfully”。问题是,在我调用conn.Close()或点击客户端上的CTRL+C之前,客户端不会刷新数据,如果我点击CTRL+C或关闭连接,客户端将退出,但不等待服务器的消息。服务器卡在这一行
n, copyErr := io.Copy(temp, conn)有没有人能帮帮我。
client.go
package main
import (
    "fmt"
    "io/ioutil"
    "net"
)
func writeMessage(conn net.Conn) {
    msg := "Hello from Client"
    _, writeErr := conn.Write([]byte(msg))
    if writeErr != nil {
        fmt.Println("Write error", writeErr)
    }
}
func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:8080")
    if err != nil {
        fmt.Println("Dial error", err)
    }
    writeMessage(conn)
    msg, err := ioutil.ReadAll(conn)
    fmt.Println("Received message", string(msg), "from", conn.RemoteAddr())
}server.go
package main
import (
    "bytes"
    "fmt"
    "io"
    "net"
    "os"
)
func handleConn(conn net.Conn) {
    localAddr := conn.LocalAddr()
    fmt.Println("Handling connection for", localAddr)
    temp := new(bytes.Buffer)
    n, copyErr := io.Copy(temp, conn)
    if copyErr != nil {
        fmt.Println("Copy error:", copyErr)
    }
    fmt.Println("Processed", n, "bytes")
    conn.Write([]byte("Successfully processed"))
}
func main() {
    ln, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Println("Error creating TCP server")
        os.Exit(1)
    }
    fmt.Println("Listening on port :8080")
    for {
        conn, err := ln.Accept()
        if err != nil {
            fmt.Println("Connection error")
        }
        handleConn(conn)
    }
}发布于 2020-04-19 21:23:04
代码阻塞在n, copyErr := io.Copy(temp, conn)上,因为它直到传入连接关闭(通过调用Close()或关闭程序)才会接收EOF。在你的例子中,你只想关闭连接的写入端。为此,TCPConn实现了CloseWrite方法。下面是一个示例,说明如何使用它:
func writeMessage(conn net.Conn) error {
    if  cw, ok := conn.(interface{ CloseWrite() error }); ok {
        defer cw.CloseWrite()
    } else {
        return fmt.Errorf("Connection doesn't implement CloseWrite method")
    }
    msg := "Hello from Client"
    _, writeErr := conn.Write([]byte(msg))
    if writeErr != nil {
        fmt.Println("Write error", writeErr)
    }
    return nil
}https://stackoverflow.com/questions/61304594
复制相似问题