2017-04-03 9 views
3

私はcurl localhost:3000 -vを呼び出してすぐに^C(取り消し)(すぐに1秒前)に電話すると、write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipeと報告するWebサーバーの例があります。応答が8kbを超えると、golang httpサーバが "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バイト(または8キロバイト)を書いている場合にのみ発生しますと結論することができました。応答全体が8192未満の場合、broken pipeエラーは返されません。

私の質問はここで、この8192バイト(または8kb)のバッファ制限が設定されていますか?これはGolangのHTTP書き込みバッファの制限ですか?これはチャンクされる応答に関連していますか?これはクライアントまたはブラウザクライアントのcurlにのみ関連していますか?この制限をどのように変更して、接続が閉じられる前に(デバッグ用に)より大きなバッファを書き込むことができますか?

ありがとうございます!

答えて

7

net/http/server.goでは、出力バッファは4<<10、つまり4KBに設定されています。

エラーが8KBで表示される理由は、クローズドリモート接続を検出するためにソケットに少なくとも2回書き込みがかかることです。最初の書き込みは成功しますが、リモートホストはRSTパケットを送信します。 2番目の書き込みは閉じたソケットに行われます。これはbroken pipeエラーを返します。

ソケットの書き込みバッファと接続レイテンシによっては、最初のRSTパケットが登録される前にさらに書き込みが成功する可能性があります。

関連する問題