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

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

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

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

ソケット

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

Android Studio

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

Q&A

解決済

1回答

2138閲覧

Android同士のソケット通信について

shalllaugh

総合スコア17

Java

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

ソケット

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

Android Studio

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

0グッド

0クリップ

投稿2019/01/13 06:32

編集2019/01/15 02:57

前提・実現したいこと:Android端末同士のソケット通信を達成したい

2つのAndroid端末を使った計算アプリケーションを開発しています。
端末Aで作成した問題を端末Bに送信

端末Bで作成した解答を端末Aに送信

という流れで進めています。

発生している問題・エラーメッセージ:解答を間違えた際、再び送信しようとしても受信しない

解答を間違えた場合に、2回目以降の解答を
端末Aが受信してくれません。

W/System.err: java.net.ConnectException: Connection refused W/System.err: at java.net.PlainSocketImpl.socketConnect(Native Method) W/System.err: at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334) W/System.err: at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196) W/System.err: at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356) W/System.err: at java.net.Socket.connect(Socket.java:586) at java.net.Socket.connect(Socket.java:535) W/System.err: at com.example.androidproject.calcpraduo.main_answer$2.doInBackground(main_answer.java:177) at com.example.androidproject.calcpraduo.main_answer$2.doInBackground(main_answer.java:164) at android.os.AsyncTask$2.call(AsyncTask.java:304) W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761)

出題側のソースコード

java

1 2public class main_setter extends AppCompatActivity { 3 /* ---------- 各変数 ---------- */ 4 /* - 状態を管理する変数 - */ 5 int state = 0; 6 7 /* - 問題式を格納する変数 - */ 8 String question = ""; 9 10 11 /* ---------- アクテビティ起動時処理 ---------- */ 12 @Override 13 protected void onCreate(Bundle saveInstanceState) { 14 super.onCreate(saveInstanceState); 15 setContentView(R.layout.ac_main_setter); 16 } 17 18  /* ---------- 問題を生成する処理を行うメソッド ---------- */ 19 public void makeQuestion(View v) { 20 21 ~省略~ 22 /* - 入力が出題の時 - */ 23 else if (chkEvent(str) == 5) { 24 setQuestion(question); 25 receiveAnswer(question); 26 } 27 28 } 29 30 /* ---------- 問題を送信する処理を行うメソッド ---------- */ 31 private void setQuestion(final String question) { 32 /* - 対象端末を指定 - */ 33 final String IPAdr 34 = "192.168.11.17"; 35 36 /* - 解放するポートを指定 - */ 37 final int port = 8080; 38 39 /* - ソケット準備 - */ 40 final InetSocketAddress isa 41 = new InetSocketAddress(IPAdr, port); 42 43 /* - 非同期通信処理 - */ 44 @SuppressLint("StaticFieldLeak") 45 AsyncTask<InetSocketAddress, Void, Void> subtask 46 = new AsyncTask<InetSocketAddress, Void, Void>() { 47 @Override 48 protected Void doInBackground( 49 InetSocketAddress... inetSocketAddresses) { 50 51 Socket sq= null; 52 53 /* - 文字列送信処理 - */ 54 try { 55 /* - 接続 - */ 56 sq = new Socket(); 57 sq.connect(isa); 58 59 /* - 出力ストリームの生成 - */ 60 BufferedWriter bw = new BufferedWriter( 61 new OutputStreamWriter(sq.getOutputStream())); 62 63 /* - 出力ストリームの送信 - */ 64 bw.write(question); 65 66 /* - ソケットのクローズ - */ 67 bw.close(); 68 sq.close(); 69 } 70 /* - 例外処理その1 - */ catch (SocketException e) { 71 e.printStackTrace(); 72 } 73 /* - 例外処理その2 - */ catch (IOException e) { 74 e.printStackTrace(); 75 } 76 return null; 77 } 78 }; 79 subtask.execute(isa); 80 } 81 82 83 /* ---------- 解答を受信する処理を行うメソッド ---------- */ 84 private void receiveAnswer(final String question) { 85 /* - 非同期通信開始 - */ 86 @SuppressLint("StaticFieldLeak") 87 AsyncTask<Void, Void, String> subtask 88 = new AsyncTask<Void, Void, String>() { 89 90 /* - 解答文字列受信準備 - */ 91 @Override 92 protected String doInBackground(Void... voids) { 93 String rs = "NG"; 94 ServerSocket ss = null; 95 BufferedReader br = null; 96 97 /* - 解答文字列受信 - */ 98 try { 99 ss = new ServerSocket(8181); 100 101 /* - 受信待機 - */ 102 Socket ws = ss.accept(); 103 104 /* - 受信文字列格納 - */ 105 br = new BufferedReader(new InputStreamReader( 106 ws.getInputStream())); 107 rs = br.readLine(); 108 109 /* - ソケットクローズ - */ 110 br.close(); 111 ws.close(); 112 ss.close(); 113 } 114 115 /* - 例外処理その1 - */ catch (IOException e) { 116 e.printStackTrace(); 117 } 118 return rs; 119 } 120 121 /* - 解答照会処理 - */ 122 @Override 123 protected void onPostExecute(String answer) { 124 125 answerMatch(question, answer); 126 } 127 }; 128 subtask.execute(); 129 }

解答側のソースコード

java

1public class main_answer extends AppCompatActivity { 2 /* ---------- 各変数 ---------- */ 3 /* - 状態を管理する変数 - */ 4 int state = 0; 5 6 /* - 生成した問題を格納する変数 - */ 7 String set_question = ""; 8 9 /* - 入力した解答を格納する変数 - */ 10 String make_answer = ""; 11 12 13 /* ---------- アクテビティ起動時処理 ---------- */ 14 @Override 15 protected void onCreate(Bundle saveInstanceState) { 16 super.onCreate(saveInstanceState); 17 setContentView(R.layout.ac_main_answer); 18 19 /* - 起動と同時に文字列受信待ち状態に移行 - */ 20 receiveAnswer(); 21 } 22 23 24 /* ---------- 問題受信処理を行うためのメソッド ---------- */ 25 private void receiveAnswer() { 26 /* - 問題表示ボックス取得 - */ 27 final TextView questionBox 28 = findViewById(R.id.question); 29 30 /* - 非同期通信処理 - */ 31 @SuppressLint("StaticFieldLeak") 32 AsyncTask<Void, Void, String> subtask 33 = new AsyncTask<Void, Void, String>() { 34 @Override 35 protected String doInBackground(Void... voids) { 36 /* -各変数の宣言 - */ 37 String rs = "NG"; 38 ServerSocket ss = null; 39 BufferedReader br = null; 40 41 /* - 文字列受信 - */ 42 try { 43 /* - ソケット作成 - */ 44 ss = new ServerSocket(8080); 45 46 /* - 受信待ち状態 - */ 47 Socket ws = ss.accept(); 48 49 /* - 受信した文字列を格納する - */ 50 br = new BufferedReader( 51 new InputStreamReader( 52 ws.getInputStream())); 53 rs = br.readLine(); 54 55 /* - クローズ - */ 56 br.close(); 57 ws.close(); 58 ss.close(); 59 } 60 /* - 例外処理その1 -*/ 61 catch (IOException e) { 62 e.printStackTrace(); 63 } 64 return rs; 65 } 66 /* - 文字列表示処理 - */ 67 @Override 68 protected void onPostExecute(String s) { 69 questionBox.setText(s); 70 } 71 }; 72 subtask.execute(); 73 } 74 75 76  /* ---------- 解答入力処理を行うためのメソッド ---------- */ 77 public void answerQuestion(View v) { 78 79  ~省略~ 80 /* - 入力が解答の時 - */ 81 if (chkEvent(str) == 5) { 82 if (!answerBox.getText().toString().equals("答 え")) 83 sendAnswer(make_answer); 84 } 85 86 } 87 88 89 /* ---------- 解答文字列送信処理を行うメソッド ---------- */ 90 private void sendAnswer(final String answer) { 91 /* -------- 通信対象端末指定 -------- */ 92 final String IP = "192.168.11.16"; 93 final int port = 8181; 94 95 /* -------- ポート設定 -------- */ 96 final InetSocketAddress isa 97 = new InetSocketAddress(IP, port); 98 99 /* -------- 非同期通信 -------- */ 100 @SuppressLint("StaticFieldLeak") 101 AsyncTask<InetSocketAddress, Void, Void> subtask 102 = new AsyncTask<InetSocketAddress, Void, Void>() { 103 104 /* ------ 文字列送信処理 ------ */ 105 @Override 106 protected Void doInBackground( 107 InetSocketAddress... inetSocketAddresses) { 108 Socket sq = null; 109 110 /* ---- 文字列送信 ---- */ 111 try { 112 113 /* -- 接続 --*/ 114 sq = new Socket(); 115 sq.connect(isa); 116 117 /* -- 出力ストリーム生成 -- */ 118 BufferedWriter bw = new BufferedWriter( 119 new OutputStreamWriter(sq.getOutputStream())); 120 121 /* -- データ送信 -- */ 122 bw.write(answer); 123 124 /* -- クローズ -- */ 125 bw.close(); 126 sq.close(); 127 } 128 129 /* ---- 例外処理1 ---- */ 130 catch (SocketException e) { 131 e.printStackTrace(); 132 } 133 /* ---- 例外処理2 ---- */ 134 catch (IOException e) { 135 e.printStackTrace(); 136 } 137 return null; 138 } 139 }; 140 subtask.execute(isa); 141 }

試したこと

恐らく出題側でソケットをcloseしていることが原因だと考えています。
以前javaのソケット通信は一度ソケットを作成したら以降同じソケットを繰り返し使うことが出来ると教わったのですが、その方法がわからないでいます。

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

Android Studio 最新ver(2019/1/14日 現在)

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

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

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

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

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

keicha_hrs

2019/01/14 15:06

「出題側のソースコード」ではsetQuestion()とreceiveAnswer()をどこから呼び出しているのか不明です。 「解答側のソースコード」ではsendAnswer()をどこから呼び出しているのか不明です。 プログラムの流れが読めないので、これでは回答は不可能です。これは実際にこういうコードになっているのでしょうか。或いは、質問フォームに転載するときのミスでしょうか。実際にこういうコードだとしたら、これでは全然動かないように思えます。
shalllaugh

2019/01/15 02:49

申し訳ありません、入力時の文字数制限で引っかかってしまい、いくつかコードを省略していました。指摘いただいた部分掲載の方してみます。
guest

回答1

0

ベストアンサー

一度ソケットを作成すれば繰り返し使うことができます。
しかし、そのソケットをCloseしてしまえばそこで終わりです。しごく当たり前の話です

Closeしなければいいだけのはなしです。

投稿2019/01/13 07:48

編集2019/01/13 07:51
y_waiwai

総合スコア87774

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

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

shalllaugh

2019/01/15 02:59

回答ありがとうございます。ソケットをcloseしなければよいとのことなのですが、ソースコード中のいずれかでcloseしておかないとアプリケーションを圧迫してしまうという話を見かけたのですが、単にcloseの部分を削除すればよいのでしょうか?
y_waiwai

2019/01/15 03:25

プログラムの終了時にcloseすればいいだけのはなしです
y_waiwai

2019/01/15 03:28

電話をかけることを想像してください。 なぜ一言言うたびに電話をかけ、わざわざ切る必要がありますか。 かけるのは最初だけ、そして、切るのは全ての通信が終わったあとでいいのです
shalllaugh

2019/01/15 03:51

なるほど、そういうことですね。ありがとうございます。ソケットのcloseについては理解できました。ということは、ソケットの準備や作成もプログラムを立ち上げる段階で行う方が良いということでしょうか?
y_waiwai

2019/01/15 07:07

サーバ側はそれこそ起動時にソケット作って終了時にCloseでいいでしょう クライアントもそれでもいいでしょうし、適宜、接続-切断してもいいでしょうね
shalllaugh

2019/01/19 09:13

ありがとうございます。少し試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問