ソケット操作のタイムアウトの設定


86

ソケットを作成するとき:

Socket socket = new Socket(ipAddress, port);

IPアドレスが使用できないため、例外がスローされますが、これは問題ありません。(テスト変数whereString ipAddress = "192.168.0.3"およびint port = 300。)

問題は、そのソケットのタイムアウトに設定するにはどうすればよいですか?

ソケットを作成するときに、UnknownHostExceptionを取得してソケットをタイムアウトにするまでの時間を短縮するにはどうすればよいですか?


10
@adrianboimvaser:その場合、重複としてフラグを立て、重複を指すコメントを残す必要があります。そうすれば、モデレーターはそのように閉じることができます(1年前にそのコメントを残しましたが、おそらく今では知っているでしょう)。私は今それをすることに投票しますが、重複がどこにあるのかわかりません!
トムアンダーソン

1
何年も遅れて返信する傾向を続けるために、@ EJPこの質問のタイトルは、あなたが提案した複製よりもはるかに曖昧ではありません
Isaac

@Isaacそして実際、それはまったく重複していないので、コメントは撤回されました。
ローン侯爵2015

(注:あいまいさを少なくするためにタイトルを微調整しました。)
Stephen C

回答:


165

代わりにSocket()コンストラクターconnect(SocketAddress endpoint, int timeout)メソッドを使用してください。

あなたの場合、それは次のようになります:

Socket socket = new Socket();
socket.connect(new InetSocketAddress(ipAddress, port), 1000);

ドキュメントからの引用

connect

public void connect(SocketAddress endpoint, int timeout) throws IOException

指定されたタイムアウト値でこのソケットをサーバーに接続します。ゼロのタイムアウトは、無限のタイムアウトとして解釈されます。その後、接続は確立されるかエラーが発生するまでブロックされます。

パラメーター:

endpoint-SocketAddress-
timeoutミリ秒単位で使用されるタイムアウト値。

スロー:

IOException-接続中にエラーが発生した
SocketTimeoutException場合-接続前にタイムアウトが期限切れになった
IllegalBlockingModeException場合-このソケットにチャネルが関連付けられていて、チャネルが非ブロッキングモードの
IllegalArgumentException場合-エンドポイントがnullであるか、このソケットでサポートされていないSocketAddressサブクラスである場合

以来:1.4


4
これにより、ConnectExceptionのタイムアウトを減らすことができます(ただし、増やすことはできません)。また、OPが取得していると主張するUnknownHostExceptionのタイムアウトには影響しません(私は信じていませんが)。また、Javadocは、デフォルトが無限大であると述べている点で正しくないことにも注意してください。そうではありません。プラットフォームのデフォルトのタイムアウトは約1分であり、これを増やすことはできません。
ローン侯爵2013年

3
4年後でもこれは役に立ちましたが、これは受け入れられた答えであるはずです。
シャープエッジ

4
それは今5年後です、そしてそれは私がインターネットで見つけた最良の答えです..ありがとう
MBH

1
socket.setSoTimeout(timeoutMillis)IO操作のブロック中にタイムアウトを呼び出すことも重要です。
灰色

43

ソケットにタイムアウトを設定するのではなく、そのソケットで実行する操作にタイムアウトを設定します。

例えば socket.connect(otherAddress, timeout)

またはsocket.setSoTimeout(timeout)read()操作のタイムアウトを設定します。

参照:http//docs.oracle.com/javase/7/docs/api/java/net/Socket.html


さて、この場合は接続も操作です。このctorが無限のタイムアウトを使用していると述べている場所は見つかりませんが、そうであるようです。
sandos 2011

3
@sandos connect()のJavadocに明確に記載されています。しかし、それも正しくありません。デフォルトのタイムアウトはプラットフォームのタイムアウトであり、無限ではなく約1分であり、このconnect()メソッドによってのみ減らすことができ、増やすことはできません。
ローン侯爵2013年

注意、socket.setSoTimeoutAFTERを呼び出す必要がありますconnect。そうしないと、効果がなく、読み取りがタイムアウトすることはありません。これは、文書化が不十分な落とし穴の1つです。
pstanton 2016

19

次の解決策を使用できます。

SocketAddress sockaddr = new InetSocketAddress(ip, port);
// Create your socket
Socket socket = new Socket();
// Connect with 10 s timeout
socket.connect(sockaddr, 10000);

それが役に立てば幸い!


1
彼が主張するように、UnknownHostExceptionが発生した場合、それは最初の行で発生し、変更されたタイムアウトは有効になりません。
ローン侯爵

ただし、最初の行は例外をスローしません。ドキュメントから:「ホスト名をInetAddressに解決しようとします。その試みが失敗した場合、アドレスは未解決としてフラグが付けられます」
ady 2016

その場合、connect()メソッドによって解決されますが、タイムアウトの制御下にはありません。
ローン侯爵

8

が原因でタイムアウトを制御することはできませんUnknownHostException。これらはDNSのタイミングです。有効なホストを指定した場合にのみ、接続タイムアウトを制御できます。上記の回答はいずれも、この点を正しく扱っていません。

しかしUnknownHostException、ホスト名ではなくIPアドレスを指定すると、実際にが表示されるとは信じがたいです。

編集JavaのDNSタイムアウトを制御するには、この回答を参照してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.