2017-04-03 42 views
3

我有一個Web服務器的例子,如果你立即調用curl localhost:3000 -v然後^C(立即取消),它會報告write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipe爲什麼golang http服務器響應超過8kb時出現「破損管道」失敗?

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寫入緩衝區中的限制嗎?這與被分塊的響應有關嗎?這僅與curl客戶端或瀏覽器客戶端有關?如何更改此限制,以便在連接關閉之前寫入更大的緩衝區(用於調試目的)?

謝謝!

回答

7

net/http/server.go中,輸出緩衝器被設置爲4<<10,即4KB。

您在8KB處看到錯誤的原因是,它至少需要2次寫入套接字才能檢測到已關閉的遠程連接。第一次寫入成功,但遠程主機發送RST數據包。第二次寫入將關閉到一個封閉的套接字,這將返回broken pipe錯誤。

根據套接字寫入緩衝區和連接延遲,有可能在註冊第一個RST數據包之前更多寫入操作可能成功。

相關問題