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

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

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

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

ソケット

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

2056閲覧

javaにおけるソケット通信について

shalllaugh

総合スコア17

Java

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

ソケット

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2018/11/30 06:25

現在2台のアンドロイド端末を用いた計算アプリケーションを開発しています。
片方を出題、片方を解答として、

出題側で問題を入力し解答側に送信

解答側で問題を受信

解答側で解答を入力し出題側に送信

出題側で解答を受信し、照会して正誤を判定する

といった流れになっています。

ここで端末間の通信にソケットを用いて、
・出題側で問題を送信する前に解答側をサーバーとして待ち状態にしてから問題を送信
・解答側で解答を送信する前に出題側をサーバーとして待ち状態にしてから解答を送信
という2つの過程を用意しました。
結果としてサーバークライアントを2セット用意することになったのですが、1度の通信だけならうまくいきました。

しかし2問目以降を処理しようと、出題側、解答側で使っていた変数を初期化し再度問題を入力。
送信を行うとするとうまく飛ばなくなってしまいました。
ソケットに関する何か問題であると考えているのですが、原因がよくわかりません。

文字数制限につき、ひとまずソケット通信部分のコードのみ掲載します。
よろしくお願いします。

出題側

java

1/* ---------- 問題文字列送信処理 ---------- */ 2 private void setQuestion(final String question) { 3 4 /* -------- 通信対象端末指定 -------- */ 5 final String IP = "192.168.11.39"; 6 final int port = 8080; 7 8 /* -------- ポート設定 -------- */ 9 final InetSocketAddress isa 10 = new InetSocketAddress(IP, port); 11 12 /* -------- 非同期通信 -------- */ 13 @SuppressLint("StaticFieldLeak") 14 AsyncTask<InetSocketAddress, Void, Void> subtask 15 = new AsyncTask<InetSocketAddress, Void, Void>() { 16 17 /* ------ 文字列送信準備 ------ */ 18 @Override 19 protected Void doInBackground( 20 InetSocketAddress... inetSocketAddresses) { 21 Socket sq = null; 22 23 /* ---- 文字列送信 ---- */ 24 try { 25 26 /* -- 接続 -- */ 27 sq = new Socket(); 28 sq.connect(isa); 29 30 /* -- 出力ストリーム生成 -- */ 31 BufferedWriter bw = new BufferedWriter( 32 new OutputStreamWriter(sq.getOutputStream())); 33 34 /* -- データ送信 -- */ 35 bw.write(question); 36 37 /* -- クローズ -- */ 38 bw.close(); 39 sq.close(); 40 } 41 42 /* ---- 例外処理1 ---- */ 43 catch (SocketException e) { 44 e.printStackTrace(); 45 } 46 47 /* ---- 例外処理2 ---- */ 48 catch (IOException e) { 49 e.printStackTrace(); 50 } 51 return null; 52 } 53 }; 54 subtask.execute(isa); 55 } 56 57 58 /* ---------- 解答文字列受信処理 ---------- */ 59 private void receiveAnswer() { 60 61 /* -------- 非同期通信開始 -------- */ 62 @SuppressLint("StaticFieldLeak") 63 AsyncTask<Void, Void, String> subtask 64 = new AsyncTask<Void, Void, String>() { 65 66 /* ------ 文字列受信準備 ------ */ 67 @Override 68 protected String doInBackground(Void... voids) { 69 String rs = "NG"; 70 ServerSocket ss = null; 71 BufferedReader br = null; 72 73 /* ---- 文字列受信 ---- */ 74 try { 75 ss = new ServerSocket(8181); 76 77 /* -- 受信待機 -- */ 78 Socket ws = ss.accept(); 79 80 /* -- 受信文字列格納 -- */ 81 br = new BufferedReader(new InputStreamReader( 82 ws.getInputStream())); 83 rs = br.readLine(); 84 85 /* -- クローズ -- */ 86 br.close(); 87 ws.close(); 88 ss.close(); 89 } 90 91 /* ---- 例外処理1 --- */ 92 catch (IOException e) { 93 e.printStackTrace(); 94 } 95 return rs; 96 } 97 98 /* ------ 解答照会処理 ------ */ 99 @Override 100 protected void onPostExecute(String answer) { 101 102 /* ---- 型変換 ---- */ 103 resultDouble = Double.parseDouble(result); 104 answerDouble = Double.parseDouble(answer); 105 106 /* ---- ポップアップ表示処理 ---- */ 107 if (answerDouble == resultDouble) { 108 makeElectPopup(); 109 } else { 110 makeMissPopup(); 111 } 112 } 113 }; 114 subtask.execute(); 115 }

解答側

java

1/* ---------- 問題文字列受信処理 ---------- */ 2 private void startSession() { 3 4 /* -------- 問題表示ボックス取得 -------- */ 5 final TextView que 6 = findViewById(R.id.question_box); 7 8 /* -------- 非同期通信開始 -------- */ 9 @SuppressLint("StaticFieldLeak") 10 AsyncTask<Void, Void, String> subtask 11 = new AsyncTask<Void, Void, String>() { 12 13 /* ------ 文字列受信準備 ------ */ 14 @Override 15 protected String doInBackground(Void... voids) { 16 String rs = "NG"; 17 ServerSocket ss = null; 18 BufferedReader br = null; 19 20 /* ---- 文字列受信 ---- */ 21 try { 22 ss = new ServerSocket(8080); 23 24 /* -- 受信待機 -- */ 25 Socket ws = ss.accept(); 26 27 /* -- 受信文字列格納 -- */ 28 br = new BufferedReader(new InputStreamReader( 29 ws.getInputStream())); 30 rs = br.readLine(); 31 32 /* -- クローズ -- */ 33 br.close(); 34 ws.close(); 35 ss.close(); 36 } 37 38 /* ---- 例外処理1 ---- */ 39 catch (IOException e) { 40 e.printStackTrace(); 41 } 42 return rs; 43 } 44 45 /* ------ 文字列表示 ------ */ 46 @Override 47 protected void onPostExecute(String s) { 48 que.setText(s); 49 } 50 }; 51 subtask.execute(); 52 } 53 54 55 /* ---------- 解答文字列送信処理 ---------- */ 56 private void sendAnswer(final String answer) { 57 58 /* -------- 通信対象端末指定 -------- */ 59 final String IP = "192.168.11.41"; 60 final int port = 8181; 61 62 /* -------- ポート設定 -------- */ 63 final InetSocketAddress isa 64 = new InetSocketAddress(IP, port); 65 66 /* -------- 非同期通信 -------- */ 67 @SuppressLint("StaticFieldLeak") 68 AsyncTask<InetSocketAddress, Void, Void> subtask 69 = new AsyncTask<InetSocketAddress, Void, Void>() { 70 71 /* ------ 文字列送信処理 ------ */ 72 @Override 73 protected Void doInBackground( 74 InetSocketAddress... inetSocketAddresses) { 75 Socket sq = null; 76 77 /* ---- 文字列送信 ---- */ 78 try { 79 80 /* -- 接続 --*/ 81 sq = new Socket(); 82 sq.connect(isa); 83 84 /* -- 出力ストリーム生成 -- */ 85 BufferedWriter bw = new BufferedWriter( 86 new OutputStreamWriter(sq.getOutputStream())); 87 88 /* -- データ送信 -- */ 89 bw.write(answer); 90 91 /* -- クローズ -- */ 92 bw.close(); 93 sq.close(); 94 } 95 96 /* ---- 例外処理1 ---- */ 97 catch (SocketException e) { 98 e.printStackTrace(); 99 } 100 /* ---- 例外処理2 ---- */ 101 catch (IOException e) { 102 e.printStackTrace(); 103 } 104 return null; 105 } 106 }; 107 subtask.execute(isa); 108 }

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

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

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

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

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

guest

回答2

0

ベストアンサー

エラーの種類がわからないのではっきりと言えないですが、2問目で、出題側を解答側に接続しようとするところで失敗しているのだとしたら、思いつくところとしては、解答側の new ServerSocket(8080) で、8080番ポートが使用中だとして BindException などが発生していないでしょうか (ログ出力を見ればわかると思います)。アプリのコード上では、ServerSocket は毎回クローズされていますが、OSが管理しているポートの利用状況には即座に反映されず、短い間に再び使おうとしたときにエラーとなっているのかもしれません。

Socket は、接続した後は、サーバー側/クライアント側関係なく双方向のデータ通信ができる仕組みですので、送信・受信の度に新しくソケットを接続しなおすのではなく、最初に一度ソケットを接続したら、それをずっと使って、問題・解答のやりとりを繰り返すのがよいと思います。

投稿2018/12/05 18:25

kafumi

総合スコア87

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

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

0

firebase realtimedatabase を使えば実装しやすそうです。

投稿2018/12/01 01:59

hinoko58

総合スコア112

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問