ユーザー定義の終了時刻までマルチキャスト ソケットからデータを読み取るコードがあります。また、スレッドがへの呼び出しThread.interrupt
によって (または他のユーザーが開始したアクションによって) 中断された場合は、データの読み取りを停止したいと思います。スレッドが中断されたときに通知を受け取る方法がわかりません。既存のコードは次のとおりです。
// These are the constants I am given
final int mcastPort = ...;
final InetAddress mcastIP = ...;
final InetAddress ifaceIP = ...; // Null indicates all interfaces should be used
final Instant endTime = ...; // Time at which to stop processing
// Initialize a datagram
final byte[] buffer = new byte[1000];
final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Process incoming datagram packets
try (final MulticastSocket socket = new MulticastSocket(port)) {
socket.joinGroup(mcastIP);
if (ifaceIP != null)
socket.setInterface(ifaceIP);
do {
final Duration soTimeout = Duration.between(Instant.now(), endTime);
socket.setSoTimeout(soTimeout);
socket.receive(packet);
// Process packet
...
} while (true);
} catch (final SocketTimeoutException e) {
// Normal condition... the recording time has ended
} catch (final ClosedByInterruptException e) {
// Uh-oh... this never happens
} ...
DatagramSocket.getChannel
を返すメソッドがあることを確認したDatagramChannel
ので、当然のことながら、基になるソケットの読み取り/書き込みには型が使用されていると想定しました。その仮定は間違っていました。つまり、MulticastSocket
は実装されていませんInterruptibleChannel
。このため、 をMulticastSocket.receive
スローすることはありませんClosedByInterruptException
。
DatagramChannel
オンラインで例を検索しましたが、上記のコードを変更して a の代わりに aを使用する方法がわかりませんMulticastSocket
。助けが必要な問題は次のとおりです。
- DatagramChannel で SO_TIMEOUT パラメータを設定するにはどうすればよいですか?
InetAddress
をNetworkInterface
オブジェクトに変換するにはどうすればよいですか?
以下は、要件を満たすために実装を からMulticastSocket
に変換する方法に関する私の最良の推測です。DatagramChannel
// Initialize a buffer
final ByteBuffer buffer = ByteBuffer.allocate(1000);
try (final DatagramChannel mcastChannel = DatagramChannel.open()) {
mcastChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
mcastChannel.connect(new InetSocketAddress(port));
mcastChannel.join(mcastIP);
if (ifaceIP != null)
// HELP: this option requires an InterfaceAddress object,
// but I only have access to an InetAddress object
mcastChannel.setOption(StandardSocketOptions.IP_MULTICAST_IF, ifaceIP);
do {
final Duration soTimeout = Duration.between(Instant.now(), endTime);
// HELP: SO_TIMEOUT is not a member of StandardSocketOptions
mcastChannel.setOption(SO_TIMEOUT, ???);
mcastChannel.receive(buffer);
// Process packet
...
} while (true);
} ...
このアプローチは機能しますか? スローできる例外の1つとしてDatagramChannel.receive
リストされていません。これが機能する場合SocketTimeoutException
は、2 番目の実装を最初の実装と同等にする方法を変更する必要があることを教えてください。そうでない場合、ユーザーの操作を介して実行を停止する方法を提供しながら、事前に定義された時間にデータグラムの受信を停止するという要件を満たす方法について、他のアイデアはありますか?ClosedByInterruptException
Thread.interrupt