Ryukalice

WindowsにおけるTCPの接続要求タイムアウト

2013-10-26

今日は、TCPで通信を行うWindows同士のクライアントサーバーシステムの、通信異常時挙動テストを行いました。で、サーバーのアプリケーションを終了した状態で、クライアントからサーバーに対して、接続要求を投げると、タイムアウトするまでに21秒という何とも中途半端な時間がかかっていました。この中途半端な時間の原因について調べました。

TCPスタックは、SYNパケットを送信してから、サーバーからSYN, ACKが返ってくるまで、一定時間待ってみます。この一定時間がデフォルトで3秒です。そして、3秒ダメならリトライしてみます。この時、倍の時間待ってみます。つまり6秒ですね。そして、デフォルトのリトライ回数は2回となっています。6秒待ってダメなら、さらにリトライしてみます。この時、再び倍の時間待ってみます。つまり12秒です。それでダメなら諦めて、タイムアウトとする訳です。

この時間が3 + 6 + 12で、合計21秒になるのです。1回目のタイムアウト時間が3秒なのも、リトライ回数が2回なのもレジストリより、設定変更が可能です。

  • キー:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
  • 初回のタイムアウト時間の値:InitialRtt (デフォルト3000[msec])
  • リトライ回数の値:TcpMaxConnectRetransmissions (デフォルト2[回])

つまり、タイムアウトの時間は以下の感じで求められるということですね。

  • 初回:t秒待ってみる。
  • 1回目のリトライ:(t * 2)秒待ってみる。
  • 2回目のリトライ:(t * 4)秒待ってみる。
  • n回目のリトライ:(n * (2 ^ (t - 1)))秒待ってみる。