回答:
1)ソケットの接続タイムアウトと読み取りタイムアウトの違いは何ですか?
接続タイムアウトは、初期接続を行う際のタイムアウトです。つまり、TCP接続ハンドシェイクを完了します。読み取りタイムアウトは、データの読み取りを待機する際のタイムアウトです1。具体的には、サーバーが最後のバイトから<timeout>秒後にバイトの送信に失敗すると、読み取りタイムアウトエラーが発生します。
2)接続タイムアウトが「無限」に設定されているとはどういう意味ですか?どのような状況で無限ループにとどまることができますか?そして、無限ループが死ぬのは何がきっかけですか?
これは、接続の試行が永久にブロックされる可能性があることを意味します。無限ループはありませんが、接続を試みると、ソケットを閉じる別のスレッドによってブロックを解除できます。(Thread.interrupt()
呼び出しもトリックを行う可能性があります...わかりません)。
3)読み取りタイムアウトが「無限」に設定されているとはどういう意味ですか?どのような状況で無限ループにとどまることができますか?無限ループが終了する原因は何ですか?
これはread
、ソケットストリームへの呼び出しが永久にブロックされる可能性があることを意味します。ここでも無限ループはありませんが、呼び出しread
によってThread.interrupt()
ソケットのブロックを解除し、(もちろん)もう一方の端でデータを送信したり、接続を閉じたりすることでブロックを解除できます。
1-それは...一人のコメンターが考えたように...ソケットが開いているか、アイドル状態でいられる時間のタイムアウトです。
これらは、TCP接続の確立およびソケットからのデータの読み取りを待機するためにJVMによって適用されるタイムアウト値です。
値が無限に設定されている場合、永遠に待つことはありません。これは単に、JVMにタイムアウトがなく、OSがすべてのタイムアウトを担当することを意味します。ただし、OSのタイムアウトは非常に長い場合があります。一部の低速ネットワークでは、タイムアウトが6分もあることがわかりました。
ソケットのタイムアウト値を設定しても、ネイティブコードでタイムアウトが発生すると機能しない場合があります。Linuxで問題を再現するには、ファイアウォールでブロックされたホストに接続するか、スイッチのケーブルを外します。
TCPタイムアウトを処理する唯一の安全なアプローチは、別のスレッドで接続コードを実行し、時間がかかりすぎる場合はスレッドに割り込むことです。
Socket.shutdownInput()
あなたの手を持たずに電話をかけることができますか?注意これらのタイムアウトは、JVMではなくTCPによって強制されます。
HttpURLConnection.getResponseCode()
apprxにぶら下がっているケースがありました。プロセスを再開するまで1週間。明らかに、JVM側でタイムアウトが設定されておらず、Linux OS側でもタイムアウトが設定されていませんでした。