http - 为什么当响应超过 8kb 时 golang http 服务器失败并显示 "broken pipe"?

标签 http curl go httpresponse

我在下面有一个示例 Web 服务器,如果您调用 curl localhost:3000 -v 然后 ^C (取消)立即(在 1 秒之前),它将报告 write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipe.

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() {
    log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            time.Sleep(1 * time.Second)

            // Why 8061 bytes? Because the response header on my computer
            // is 132 bytes, adding up the entire response to 8193 (1 byte 
            // over 8kb)
            if _, err := w.Write(make([]byte, 8061)); err != nil {
                    fmt.Println(err)
                    return
            }   
    })))
}

根据我的调试,我已经能够得出结论,只有当整个响应写入超过 8192 字节(或 8kb)时才会发生这种情况。如果我的整个响应写入少于 8192,则不会返回 broken pipe 错误。

我的问题是这个 8192 字节(或 8kb)的缓冲区限制设置在哪里? 这是 Golang 的 HTTP 写缓冲区的限制吗?这与响应被分 block 有关吗?这只与 curl 客户端或浏览器客户端有关吗?如何更改此限制,以便在关闭连接之前写入更大的缓冲区(用于调试目的)?

谢谢!

最佳答案

net/http/server.go输出缓冲区设置为 4<<10 ,即 4KB。

您在 8KB 处看到错误的原因是,至少需要 2 次写入套接字才能检测到已关闭的远程连接。第一次写入成功,但远程主机发送 RST 数据包。第二次写入将写入一个关闭的套接字,这就是返回 broken pipe 的原因。错误。

根据套接字写入缓冲区和连接延迟,在注册第一个 RST 数据包之前,可能会有更多的写入成功。

关于http - 为什么当响应超过 8kb 时 golang http 服务器失败并显示 "broken pipe"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43189375/

相关文章:

azure - 如何使用 DefaultAzureCredential 类创建 Azure 存储 SAS token

html - 在 Go 中制作网络应用程序?

java - 浏览器发送 CONNECT 请求后,创建代理无法通过 SSL 正确建立隧道?

使用现有帐户 Curl 登录

java - 从 POST 保存分割上传的文件最终会变成空

curl - 在curl响应主体末尾自动添加换行符

json - 将变量注入(inject) JSON 配置文件

java - 轴2选项: setAction()

rest - HTTP 客户端如何向服务器请求最新数据/刷新缓存?