最近P2Pにお熱/ソケットの勉強 - Scala
どうもポポです。
最近研究をやらずにP2Pの勉強ばかりしています。
というのもP2Pで動画キャッシュを共有できるアプリケーションを書いてみたいんですよね。
公開とかはまだまだ先になるかもしれないんですけど、がんばります。
さてその前にもっと基本的な部分を実験したみたい!ということで今日はソケットの実験を
やってみたいと思います。
ここでソケットの実験をやっているJavaのコードがあったのでこれをScalaで書こうかと思ったのですが、ちょっとコンパイルがうまくいかないとかなんとかあったので、こっちのscalaのサンプルコードを使ってみました。
・Server版
import java.io._ import java.net.{InetAddress,ServerSocket,Socket,SocketException} import java.util.Random object randomserver { def main(args: Array[String]): Unit = { try { println("クライアントからの接続をポート5555で待ちます") val listener = new ServerSocket(5555) while (true) new ServerThread(listener.accept()).start() listener.close() } catch { case e: IOException => System.err.println("Could not listen on port: 5555.") System.exit(-1) } } } case class ServerThread(socket: Socket) extends Thread("ServerThread") { override def run(): Unit = { val rand = new Random(System.currentTimeMillis()) try { val out = new DataOutputStream(socket.getOutputStream()) val in = new ObjectInputStream(new DataInputStream(socket.getInputStream())) val filter = in.readObject().asInstanceOf[Int => Boolean] while (true) { var succeeded = false; do { val x = rand.nextInt(1000); succeeded = filter(x); if (succeeded) out.writeInt(x) } while (! succeeded); Thread.sleep(100) } out.close() in.close() socket.close() } catch { case e: SocketException =>() // avoid stack trace when stopping a client with Ctrl-C case e: IOException => e.printStackTrace() } } }
・Cilent版
import java.io._ import java.net.{InetAddress,ServerSocket,Socket,SocketException} import java.util.Random object randomclient { def main(args: Array[String]) { val filter: Int => Boolean = try { Integer.parseInt(args(0)) match { case 1 => x: Int => x % 2 != 0 case 2 => x: Int => x % 2 == 0 case _ => x: Int => x != 0 } } catch { case _ => x: Int => x < 100 } try { val ia = InetAddress.getByName("localhost") val socket = new Socket(ia, 5555) val out = new ObjectOutputStream(new DataOutputStream(socket.getOutputStream())) val in = new DataInputStream(socket.getInputStream()) out.writeObject(filter) out.flush() while (true) { val x = in.readInt() println("x = " + x) } out.close() in.close() socket.close() } catch { case e: IOException => e.printStackTrace() } } }
少し混ぜ混ぜしてますが、ちゃんと動くようですね。Socketの勉強になりましたでしょうかね?
流れとしては
・server版:サーバソケットで待ちポート指定→出力ストリーム取得→入力ストリーム取得→ごにょごにょ→順に閉じる
・client版:ソケット生成→出力ストリーム取得→入力ストリーム取得→ごにょごにょ→順に閉じる
ってな感じなのかなぁ。確かに感覚的にはわかった感じがするんだけど、理解していないような気がする。
ってかScalaむじぃ