Go 中 HTTP ResponseWriter 的写函数会缓冲吗?

假设我们有一个处理 HTTP 请求的函数,例如:


func handler(w http.ResponseWriter,  r *http.Request) {

    w.Write([]byte("first piece of data"))

    // do something

    w.Write([]byte("second piece of data"))

}  

我想知道第一次调用 w.Write() 是否刷新到客户端?


如果它被刷新,那么我们实际上对客户端响应了两次,这很奇怪,因为我们如何Content-Length在第二次调用 write 之前确定?


如果它没有被刷新(比如数据在本地缓冲),那么如果我们在第一次调用时写入大量数据怎么办?(那个堆栈会溢出吗?)


杨__羊羊
浏览 164回答 1
1回答

慕妹3146593

我想知道第一次调用 w.Write() 是否刷新到客户端?net/http的默认值ResonseWriter在net.Conn它写入的内容上有一个(当前为 4KB)大的输出缓冲区。此外,操作系统通常会缓冲对套接字的写入。所以在大多数情况下会发生某种缓冲。如果它被刷新,那么我们实际上对客户端响应了两次,这很奇怪,因为我们如何在第二次调用 write 之前确定 Content-Length?好吧,HTTP 1.1 允许持久连接。此类响应通常不包含Content-Length标题。此外,还有 HTTP 预告片。如果您的客户端不支持 HTTP 1.1 和持久连接,它们将有某种读取超时,在此期间您可以根据需要多次写入连接;这是一种回应。与 Go 相比,这更多地与 TCP 套接字和 HTTP 实现的性质有关。如果它没有被刷新(比如数据在本地缓冲),那么如果我们在第一次调用时写入大量数据怎么办?(那个堆栈会溢出吗?)不,在堆栈上分配缓冲区是没有意义的——缓冲区的主体将存在于堆中。如果您达到每个进程的内存限制,您的应用程序将出现“内存不足”的恐慌。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go