DatagramChannel(UDP)のsetOption
小ネタ。
UDPで何かしたいときのためのDatagramChannelってクラスがあって、ソケットに対してオプションを設定したい時…
import java.net.StandardSocketOptions import java.nio.channels.DatagramChannel import java.net.StandardProtocolFamily object Setopt { def main(args: Array[String]) = { val channel = DatagramChannel.open(StandardProtocolFamily.INET) // まず、SO_REUSEADDRを有効にするコードをここに書きたい } }
そのままsetOptionという、使えそうなメソッドがあるので使います。
public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value)
渡すのはSO_REUSEADDRに相当する値。
public static final SocketOption<Boolean> SO_REUSEADDR
さて、setOptionに定数を渡して…
// SO_REUSEADDRを有効にするコード channel.setOption(StandardSocketOptions.SO_REUSEADDR, true)
Setopt.scala:9: error: type mismatch; found : java.net.SocketOption[java.lang.Boolean] required: java.net.SocketOption[Any] Note: java.lang.Boolean
ぁぁ?型指定しろって言われてます。直そう。
// SO_REUSEADDRを有効にするコード channel.setOption[Boolean](StandardSocketOptions.SO_REUSEADDR, true)
Setopt.scala:10: error: type mismatch; found : java.net.SocketOption[java.lang.Boolean] required: java.net.SocketOption[scala.Boolean] channel.setOption[Boolean](StandardSocketOptions.SO_REUSEADDR, true) ^ one error found
おう、ちゃんとJavaの型を渡せと。こりゃうっかり。
// SO_REUSEADDRを有効にするコード channel.setOption[java.lang.Boolean](StandardSocketOptions.SO_REUSEADDR, true)
なんだか嫌な感じの見た目ですが、これで完成。
ところで、DatagramChannelは中のsocketがすぐ引っ張り出せるので…
channel.socket.setReuseAddress(true)
こう書けます。呼び出し階層はひとつ増えてるものの、文字数は少ない。
しかし、せっかくChannelで包んでいて、そこに操作インターフェイスがあるのに、結局生ソケットを触るのはなんだ複雑な気分です。
Javaで試したら、型指定なしでもすんなり動くようなのですが。
import java.net.StandardSocketOptions; import java.nio.channels.DatagramChannel; import java.net.StandardProtocolFamily; import java.io.*; class SetOpt { public static void main(String[] args) throws IOException { DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET); channel.setOption(StandardSocketOptions.SO_REUSEADDR, true); } }