首页 > 解决方案 > net.Conn 从未收到 EOF

问题描述

我正在尝试通过 TCP 连接发送 HTTP 请求net.Conn并读取后续响应,但在读取时我似乎从未收到EOF来自连接的响应。这使得函数像io.Copyioutil.ReadAll无用,因为它们永远阻塞。

代码:

client.go

const requestString = "GET /test HTTP/1.1\r\n" + "Host: 127.0.0.1:8080\r\n\r\n"

func main() {
    dialer := net.Dialer{}
    conn, err := dialer.Dial("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Fatalln(err)
    }

    defer conn.Close()

    _, err = conn.Write([]byte(requestString))
    if err != nil {
        log.Fatalln(err)
    }
    
    buf := make([]byte, 1024)
    data := make([]byte, 0)
    length := 0

    for {
        n, err := conn.Read(buf)
        if err != nil {
            if err != io.EOF {
                fmt.Printf("Read error: %v\n", err)
            }
            break
        }

        data = append(data, buf[:n]...)
        length += n
        fmt.Printf("Partial read:\n%s\n", string(buf[:n]))
    }

    fmt.Println("Response:")
    fmt.Println(string(data))
}

server.go

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %s", r.URL.Path[1:])
    })
    http.ListenAndServe(":8080", nil)
}

client.go已经运行的运行输出server.go

Partial read:
HTTP/1.1 200 OK
Date: Wed, 25 Nov 2020 04:09:32 GMT
Content-Length: 11
Content-Type: text/plain; charset=utf-8

Hello, test

第一次调用Read()返回预期的响应,但缺少EOF. 随后的调用Read()永远挂起,我不确定如何确定连接何时完成。如果我中断服务器进程,客户端连接会正确关闭并且响应完成。

我如何 a) 接收EOF或 b) 确定响应何时完成?我在网上看到的所有示例都与我的代码接近,所以我不确定我做错了什么。

标签: httpgotcp

解决方案


添加Connection: close到请求标头可确保连接......好吧,关闭。


推荐阅读