我在下面有一个web服务器示例,如果您立即(在1秒之前)拨打curl localhost:3000 -v然后拨打^C(取消),它将报告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错误.

我的问题是where is this 8192 bytes (or 8kb) buffer limit set?这是Golang的HTTP写缓冲区的限制吗?这与被分块的响应有关吗?这只与curl客户端或浏览器客户端有关吗?如何更改此限制,以便在连接关闭之前写入更大的缓冲区(用于调试)?

谢谢!

推荐答案

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

您看到错误大小为8KB的原因是,向套接字写入至少2次才能检测到关闭的远程连接.第一次写入成功,但远程主机发送RST数据包.第二次写入将写入关闭的套接字,这就是返回broken pipe错误的内容.

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

Go相关问答推荐

golang gin何时使用收件箱上下文以及何时重定向

golang-jWT签名无效

如何描述OpenAPI规范中围棋的数据类型.JSON?

你能把用户界面文件中的GTK4应用程序窗口添加到GTK4应用程序中吗?

如何在gofr发起的服务间调用请求中添加Authorization Header?

Golang内置打印(Ln)函数&S行为怪异

调用库和直接操作效率有区别吗?

如何创建在responseWriter.Write 上返回错误的http.ResponseWriter 模拟实例?

将字符串格式的x509证书生成主题名称

是否可以在调试期间在 VSCode 中预览 github.com/shopspring/decimal 值?

从单词中删除特殊字符

如何在 `hashicorp / terraform-exec` 中将 `ApplyConfig` 传递给 `tf.Apply()`?

如何使用管理员权限启动 powershell 进程并重定向标准输入 (os.exec)

致命错误 - 所有 Goroutines 都睡着了!僵局

通过环境变量配置 OTLP 导出器

分配空切片而不引用其类型?

使用 bolthold 3 条件进行 boltDB 查询

如何从字符串中删除多个换行符`\n`但只保留一个?

Go:为一组单个结果实现 ManyDecode

手动下载并放置一个 golang mod 文件