質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Q&A

解決済

1回答

638閲覧

Scala(java)におけるソケット通信プログラムの処理順について

yutoS

総合スコア13

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

0グッド

0クリップ

投稿2018/11/30 05:14

前提・実現したいこと

ScalaとScalaFXを使用したソケット通信オセロプログラミングを作成しています。
ソケット通信自体はうまくいきましたが、通信後のオセロを盤面に描画する際に思った通りの動作をしなくて困っています。

発生している問題・エラーメッセージ

ソケット通信がサーバー・クライアント間で完了したのち、お互いにメッセージのやりとりをして、そのメッセージに沿って黒丸or白丸を描画する際に、即座に描画したいのですが、自分の盤面をクリックした際に、相手からの応答があってから相手の円と自分の円が同時に描画されます。これを即座に描画するようにしたいです。

該当のソースコード

Scala 2.12.7

OseloContoroller.scala

package gui import java.net.Socket import scalafx.Includes._ import scalafx.scene.input.MouseEvent import scalafx.scene.paint.Color._ import scalafx.scene.layout.GridPane import scalafxml.core.macros.sfxml import javafx.scene.shape.Circle import scalafx.scene.paint.Color import network._ import scalafx.scene.control.Button @sfxml class OseloController(val board: GridPane, val connecteButton: Button, val serverButton: Button){ val server: Server = new Server(8000, board) var client: Client = _ var flag: Boolean = _ //白黒の順番判定trueが黒、falseが白 var posX:Int = _ var posY:Int = _ serverButton.onMouseClicked = (_: MouseEvent) =>{ server.createServer flag = true } connecteButton.onMouseClicked = (_: MouseEvent) =>{ val sc: Socket = new Socket("127.0.0.1", 8000) client = new Client(sc, board) flag = false client.createClient() client.receiveMsg() } board.onMouseClicked = (e:MouseEvent) => { posX = (e.x / 53).asInstanceOf[Int] posY = (e.y / 53).asInstanceOf[Int] if(flag) { server.sendMsg(posX.toString + "," + posY.toString) server.receiveMsg() }else{ client.sendMsg(posX.toString + "," + posY.toString) client.receiveMsg() } } }

Server.scala

package network import java.io._ import java.net._ import javafx.scene.shape.Circle import scalafx.scene.layout.GridPane import scalafx.scene.paint.Color import scalafx.scene.paint.Color._ class Server(val port: Int, val board: GridPane) extends Thread{ var ss: ServerSocket = _ var sc: Socket = _ var br: BufferedReader = _ var pw: PrintWriter = _ var clientMsg: String = _ var arr: Array[String] = _ def createServer: Unit ={ try{ ss = new ServerSocket(port) println("Waiting For・・・") sc = ss.accept() println("Welcome!!") //以下、メッセージやり取りのための変数初期化 try { br = new BufferedReader(new InputStreamReader(sc.getInputStream)) pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sc.getOutputStream))) }catch { case e: Exception => e.printStackTrace } } catch { case e:Exception => e.printStackTrace ss.close() } } def createCircle(posX: Int, posY: Int, color: Color): Unit ={ println("Server:" + posX + "," + posY) board.add(new Circle(0,0,27,color), posX , posY) } def sendMsg(msg: String): Unit = { arr = msg.split(",") pw.println(msg) pw.flush() createCircle(arr(0).toInt, arr(1).toInt, Black) } def receiveMsg(): Unit ={ while((clientMsg = br.readLine()) == null){Thread.sleep(100)} println(clientMsg) arr = clientMsg.split(",") createCircle(arr(0).toInt, arr(1).toInt, White) } }

Client.scala

package network import java.io._ import java.net._ import java.util._ import javafx.scene.shape.Circle import scalafx.scene.paint.Color._ import scalafx.scene.layout.GridPane import scalafx.scene.paint.Color class Client(val sc: Socket, val board: GridPane){ var br: BufferedReader = _ var pw: PrintWriter = _ var serverMsg: String = _ var arr: Array[String] = _ def createClient(): Unit ={ try { br = new BufferedReader(new InputStreamReader(sc.getInputStream)) pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sc.getOutputStream))) }catch { case e: Exception => e.printStackTrace } } def createCircle(posX: Int, posY: Int, color: Color): Unit ={ println("Client:" + posX + "," + posY) board.add(new Circle(0,0,27,color), posX , posY) } def sendMsg(msg: String): Unit = { arr = msg.split(",") pw.println(msg) pw.flush() createCircle(arr(0).toInt, arr(1).toInt, White) } def receiveMsg(): Unit ={ while((serverMsg = br.readLine()) == null){Thread.sleep(100)} println(serverMsg) arr = serverMsg.split(",") createCircle(arr(0).toInt, arr(1).toInt, Black) } }

試したこと

createCircle関数の挿入位置を、変えたりしました。要は、reciveMsg関数内部の処理がブロッキングだと思うので、それ以降応答が止まるのはわかるのですが、その前に描画処理をしているにもかかわらず、(中のprintln関数は走ったので、正しく処理に入って入る)円の描画が行われません。

補足情報(FW/ツールのバージョンなど)

scala 2.12.7
scalar 8.0.144
jdk-9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rysh

2018/12/07 23:54

build.sbtなどが無いとコード動かさないので、まとめてgithubにコードをあげてくれたら調べてみたいです。
guest

回答1

0

自己解決

こちら自己解決しました。
https://qiita.com/yuto_suzuki/items/c3de758d9f2f099166bd

結局は、メッセージの待ち受けを別スレッドで行うことで、画面描画をスムーズに行えるということがわかりました。

投稿2018/12/11 15:58

yutoS

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問