web-dev-qa-db-ja.com

データの再送信とWSAECONNABORTED(10053)ソケットエラー

互いに接続されている2つのソケットがあるとします(_Socket A_と_Socket B_)。

_Socket B_のあるコンピューターの電源が切断されている場合、_Socket A_がデータを_Socket B_に送信しようとすると、データは確認応答されないため、TCPはTCPが諦め、データを再送信しないことを決定し、_Socket A_にソケットエラーWSAECONNABORTED (10053)が発生したことを通知するまで、確認応答を期待してデータを何度も再送信します。 。

私の質問は次のとおりです。

  • 再送信を何度か再試行した後、常にソケットエラーWSAECONNABORTED (10053)が発生することが保証されていますか(そうでない場合はTCPが永久に再送信し続けるためです!)?
  • TCPが諦め、WSAECONNABORTED (10053)ソケットエラーを引き起こすまでに何回の再送信の再試行が必要ですか?
  • この再送信の再試行回数は構成可能ですか?
5
user455236

TCP)のWindowsタイマーは、推定 ラウンドトリップ時間)に基づく再送信タイムアウト(RTO)と呼ばれる時間の単位を使用します (またはRTT)送信者と受信者の間、およびこのラウンドトリップ時間の変動。このタイマーの動作は RFC 6298 で指定されています。詳細については、Wikipediaの記事-を参照してください。 伝送制御プロトコル

Windowsでの動作は次のとおりです。

  1. 推定RTOが最初に確立されます
  2. TCPメッセージが送信され、ACK(確認)パケットを待ちます
  3. ACKが到着していない場合は、待機時間を2倍にして、手順2に戻ります。
  4. ACKを受信すると、新しいRTOが計算されます
  5. ACKが受信されない場合、接続はエラーWSAECONNABORTEDで中止されます。

Windowsは、このMicrosoftの記事で説明されているように、このプロトコルに2つのレジストリパラメータを使用します。
TCP/IPの最大再送信タイムアウトを変更する方法

TcpMaxDataRetransmissions

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters

Value Name:  TcpMaxDataRetransmissions
Data Type:   REG_DWORD - Number
Valid Range: 0 - 0xFFFFFFFF
Default:     5

説明:

このパラメータは、接続を中止する前にTCPが個々のデータセグメント(非接続セグメント)を再送信する回数を制御します。再送信タイムアウトは、接続での連続した再送信ごとに2倍になります。リセットされます。応答が再開したとき。基本タイムアウト値は、接続で測定されたラウンドトリップ時間によって動的に決定されます。

TCPInitialRtt

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ID for Adapter

Value Name:  TCPInitialRtt
Data Type:   REG_DWORD
Valid Range: 300-65535 (milliseconds in decimal)
Default:     0xBB8 (3000 milliseconds expressed in hexadecimal)

説明:

このパラメータは、新しい接続ごとにTCP)によって使用される初期再送信タイムアウトを制御します。これは、接続要求(SYN)および各接続で送信される最初のデータセグメントに適用されます。たとえば、「5000decimal」の値データは最初の再送信時間を5秒に設定します。

注:値を増やすことができるのは、最初のタイムアウトの場合のみです。値の減少はサポートされていません。

TCPInitialRttは3秒の初期タイムアウトで開始しますが、パケットが正しく送信されると、より妥当な値に平滑化されます。

たとえば、これがどのように機能するかについて、デフォルト値の3秒のRTOと5回の再試行を使用すると、合計待機時間は次のようになります。

  1. 最初のタイムアウト時間:3秒
  2. 2番目のタイムアウト:6秒
  3. 3番目のタイムアウト:12秒
  4. 4番目のタイムアウト:24秒
  5. 5番目で最後のタイムアウト:48秒

これにより、接続が中止されるまでの合計待機時間は93秒になります。ほとんどの場合、接続が正しく機能したことがあれば、タイムアウトははるかに少なくなります。

2
harrymc

通常、timeが使用されます(タイムアウト値に達するまで再試行を続けます )、ただし、クライアント/サーバーソフトウェアがどのように作成されているかによって異なります。

時間を使用する場合、再試行の回数を知るには、再試行が発生する頻度を知る必要があります。

プログラムがWinsockを使用している場合にタイムアウトを設定するための可能な方法については、以下を参照してください。

ソフトウェアは、失敗する前に再試行回数または時間を使用するように作成することもできます。 )失敗する前、または両方の組み合わせ。


出典 WinsockプログラマーのFAQ

2.15-Winsock関数のタイムアウトを変更するにはどうすればよいですか?

一部のブロッキングWinsock関数(connect()など)には、タイムアウトが組み込まれています。この背後にある理論は、適切なタイムアウトを設定するために必要なすべての情報をスタックだけが持っているというものです。それでも、スタックが使用する値がアプリケーションには長すぎることに気付く人もいます。 1分以上かかる場合があります。

Send()およびrecv()のタイムアウトは、SO_SNDTIMEOおよびSO_RCVTIMEOのsetsockopt()オプションを使用して調整できます。 。

他のWinsock関数の場合、最善の解決策は、ソケットを完全にブロックしないようにすることです。すべての非ブロッキングソケットメソッドは、カスタムタイムアウトを構築する方法を提供します。

  • Select()を使用したノンブロッキングソケット– select()関数の5番目のパラメーターはタイムアウト値です。

  • 非同期ソケット– Windows API SetTimer()を使用します。

  • イベントオブジェクト– WSAWaitForMultipleEvents()にはタイムアウトパラメータがあります。

  • 待機可能なタイマー– CreateWaitableTimers()を呼び出して待機可能なタイマーを作成し、ソケットと一緒にWSAEventSelect()などの関数に渡すことができます。タイマーがオフになる前にソケットのいずれも通知されない場合、ブロッキング関数はとにかく戻ります。

非同期ソケットと非ブロッキングソケットを使用すると、タイムアウトの処理を完全に回避できる場合があることに注意してください。 Winsockがビジー状態でも、プログラムは機能し続けます。そのため、時間がかかりすぎる操作をキャンセルするか、コードでこの機能を引き継ぐのではなく、Winsockの自然なタイムアウトを期限切れにするかはユーザーに任せることができます。

0
DavidPostill