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

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

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

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

ソケット

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

Q&A

解決済

2回答

5590閲覧

ソケット通信について

shalllaugh

総合スコア17

Java

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

ソケット

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

1グッド

2クリップ

投稿2019/01/20 08:11

編集2019/01/20 14:11

前提・実現したいこと

socketを用いたプログラミングで、同じsocketを繰り返し使用する方法を知りたいです。
socketは非同期で処理しており、文字列の送受信にはstreamを用いています。

試したこと

sokcetやstreamの宣言を最初に行い、
プログラムの終了時に全てcloseする形を考えました。
終了時にもtry-catchも組み込んだのですがうまくいきません。

色々と調べたのですが、どれも通信を一回だけするサンプルばかりで、
同じsocketを繰り返し使用するサンプルが見つかりませんでした。

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

ツール:Android Studio
言語:Java

closeをしていないので、
socket自体は生きているがInputStreamやOutputStream、
それぞれのBufferedをcloseしてしまっているから
文字列の送受信が繰り返して行えないのでしょうか?

参考にできそうなURLなどでもありがたいので、よろしくお願い致します。

ソースコード

Java

1private void clientAnswerSocket() { 2 try { 3 // サーバーのポート番号を指定 4 clientAnswerSocket 5 = new ServerSocket(50005); 6 7 // 正解を受信するまでループ 8 while (loop) { 9 // 接続待機 10 acSocket = clientAnswerSocket.accept(); 11 12 // 受信ストリームの取得 13 isr = new InputStreamReader(acSocket.getInputStream()); 14 br = new BufferedReader(isr); 15 ra = br.readLine(); 16 17 answerDouble = Double.parseDouble(ra); 18 19 if(questionDouble == answerDouble) { 20 loop = false; 21 } 22 } 23 24 // ソケットを閉じる 25 acSocket.close(); 26 } 27 // 例外処理 28 catch (IOException e) { 29 e.printStackTrace(); 30 } 31 finally { 32 try { 33 // 解答の表示 34 if(br != null) { 35 br.close(); 36 } 37 if(isr != null) { 38 isr.close(); 39 } 40 } 41 // 例外処理 42 catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 } 47 48  この他、socketのcloseはプログラムを終了させる位置など別の場所で記述しています。
keicha_hrs👍を押しています

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

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

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

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

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

keicha_hrs

2019/01/20 09:14 編集

Socket.IOはこの質問につけるタグには適していないので外してください。「ソケット」と誤りましたかね?
shalllaugh

2019/01/20 09:39

そうですね、間違えました。教えて下さりありがとうございます。
y_waiwai

2019/01/20 11:06 編集

うまくいかないとはどううまくいかないんでしょう また、ソースがないと回答しようもありませんが
shalllaugh

2019/01/20 12:13

すみません、またしても文字入力制限に引っかかってしまったので、なるべくコードを掲載しないようにしてしまいました。 強制終了してしまい正常な運用が出来ないということで、デバックをしようにも自分で記述していないコードへジャンプしてしまうため困っている感じです。
jimbe

2019/01/25 12:28

まだ解決済みとなっていないようなので質問があります. 168558 では「Android同士のソケット通信について」として「解答を間違えた際、再び送信しようとしても受信しない」とされていました. accept で得た Socket とともに ServerSocket まで close していたのが原因のようですが, この 169850 で「同じsocketを繰り返し使用する方法を知りたい」とされています. ここまで(主に) keicha_hrs さんとのやり取りでは ServerSocket の繰り返し使用(とは普通言わないと思いますが) について回答を得ていらっしゃいますが, つまりここまで socket と表現されていたのは ServerSocket のことだったということなのでしょうか. というのも, てっきり出題側がサーバ, 回答側がクライアントとしての構成かと思い, 回答側が出題側に接続すると問題が送信され, 回答側が回答を送り返し, 出題側で判定して結果を回答側に送信し, 正解となるまで再回答→再判定を繰り返すために, その経路となる(ServerSocket.accept から戻された) Socket を「繰り返し使用」する方法をご質問かと思ったものですから.
shalllaugh

2019/01/30 05:04

168558の質問で頂いた回答を実践してみたのですが、解答の再受信が出来なかったので、似たような質問として新しく立てさせていただきました。質問内で表現しているsocketはServerSocketのことだと思います。socketについては独学で、Javaのリファレンスやインターネットの検索でsokcetに関する情報を得ています。そのため間違った情報や正しくない表現をしてしまっているかもしれません。jimbe様の考えていらっしゃる流れで概ね間違いはありませんが、本システムでは出題側と解答側がそれぞれサーバーとクライアントを担っています。その際に使用しているsocketは別物です。1つのsocketによるデータの送受信が本来の使い方ということは調べて知っているのですが、その使い方がわからず現在の形で落ち着いています。
jimbe

2019/01/30 05:39

もしご参考になるようであればそのようなコードを書いてみようと思うのですが, 如何でしょうか.
shalllaugh

2019/01/30 06:42

本当ですか?ありがとうございます。是非お願いします。
guest

回答2

0

普通にクライアント-サーバではどういう感じになるかということで書いてみました.
すいません, 動くものにしようと書いていますが, 一気に書いた状態でまだ動かしていません.
レイアウトはクライアント側で, 問題表示TextView id=question, 回答欄EditText id=answer, 判定表示TextView id=result, 回答送信Button id=finalAnswer です. ボタンは全問題終了時のクライアント終了も兼ねています.
サーバ側は使っていません.
説明を入れてみましたが, 修正すると書き込みが大きすぎになるようで消さざるをえませんでした. あくまで参考ということでお願いします.
流れを図にしてみました.
イメージフロー

java

1public class ServerActivity extends AppCompatActivity { 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 //setContentView(R.layout.activity_server); 6 try { 7 new Thread(new Server("0.0.0.0",8080)).start(); 8 } catch (IOException e) { 9 e.printStackTrace(); 10 } 11 } 12 private class Server implements Runnable { 13 private String host; 14 private int port; 15 Server(String host, int port) throws IOException { 16 this.host = host; 17 this.port = port; 18 } 19 @Override 20 public void run() { 21 Log.d("Server", "アドレス="+host+", ポート="+port); 22 ServerSocket ss = null; 23 try { 24 ss = new ServerSocket(); 25 ss.bind(new InetSocketAddress(host, port)); 26 while(true) { 27 Log.d("Server.run", "accept()"); 28 Socket s = ss.accept(); 29 Log.d("Server.run", "s="+s); 30 new Questioner().execute(s); 31 } 32 } catch (IOException e) { 33 Log.e("Server.run", "IOException", e); 34 } finally { 35 if(ss != null) try { ss.close(); } catch (IOException ignore) {} 36 } 37 } 38 } 39 private class Questioner extends AsyncTask<Object, Object, String> { 40 @Override 41 protected String doInBackground(Object... objects) { 42 Socket s = (Socket)objects[0]; //パラメータ1つめは Socket. 43 try { 44 BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 45 BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream())); 46 Question q; 47 for(int number=1; (q = createQuestion(number)) != null; number++) { 48 Log.d("Questioner.doInBackground", "問題送信 linecount="+q.linecount+", text="+q.text); 49 w.write(q.linecount+"\n"); 50 w.write(q.text); 51 w.flush(); 52 String result; 53 do { 54 Log.d("Questioner.doInBackground", "回答受信"); 55 String answer = r.readLine(); 56 Log.d("Questioner.doInBackground", "answer="+answer); 57 if(answer == null) return null; 58 result = answer.equals(q.correctAnswer) ? "OK" : "NG"; 59 Log.d("Questioner.doInBackground", "判定送信 result="+result); 60 w.write(result + "\n"); 61 w.flush(); 62 } while (result.equals("NG")); 63 } 64 Log.d("Questioner.doInBackground", "終了送信"); 65 w.write("0\n"); 66 w.flush(); 67 } catch (IOException e) { 68 Log.e("Questioner.doInBackground", "異常", e); 69 } finally { 70 try { s.close(); } catch(IOException ignore) {} 71 } 72 return null; 73 } 74 private class Question { 75 final int linecount; 76 final String text; 77 final String correctAnswer; 78 Question(int linecount, String text, String correctAnswer) { 79 this.linecount = linecount; 80 this.text = text; 81 this.correctAnswer = correctAnswer; 82 } 83 } 84 private Question createQuestion(int questionNumber) { 85 switch(questionNumber) { 86 case 1: return new Question(3, 87 "2019年1月1日は何曜日?\n1=月曜日, 2=火曜日, 3=水曜日\n4=木曜日, 5=金曜日, 6=土曜日\n", 88 "2"); 89 case 2: return new Question(1, 90 "1+2=?\n", 91 "3"); 92 } 93 return null; 94 } 95 } 96}

java

1public class ClientActivity extends AppCompatActivity { 2 private TextView questionView; 3 private EditText answerView; 4 private TextView resultView; 5 private Button finalAnswer; 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_client); 10 questionView = (TextView)findViewById(R.id.question); 11 answerView = (EditText)findViewById(R.id.answer); 12 resultView = (TextView)findViewById(R.id.result); 13 finalAnswer = (Button)findViewById(R.id.finalAnswer); 14 finalAnswer.setOnClickListener(new View.OnClickListener() { 15 @Override 16 public void onClick(View v) { 17 String answer = answerView.getText().toString(); 18 if(answer.length() == 0) return; 19 new ResultReceiver().execute(answer); 20 } 21 }); 22 manager = new ConnectionManager("10.0.2.2", 8181); 23 new QuestionReceiver().execute(); 24 } 25 private ConnectionManager manager; 26 private class ConnectionManager { 27 private String host; 28 private int port; 29 private Socket s; 30 private BufferedWriter w; 31 private BufferedReader r; 32 ConnectionManager(String host, int port) { 33 this.host = host; 34 this.port = port; 35 } 36 void connect() throws IOException { 37 if(s == null) { 38 Log.d("ConnectionManager.connect", "接続"); 39 s = new Socket(host, port); 40 try { 41 w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 42 r = new BufferedReader(new InputStreamReader(s.getInputStream())); 43 Log.d("ConnectionManager.connect", "接続成功"); 44 } catch(IOException e) { 45 Log.e("ConnectionManager.connect", "接続失敗", e); 46 try { s.close(); } catch(IOException ignore) {} 47 s = null; w = null; r = null; 48 throw e; 49 } 50 } 51 } 52 BufferedReader getReader() throws IOException { connect(); return r; } 53 BufferedWriter getWriter() throws IOException { connect(); return w; } 54 void disconnect() { if(s == null) try { s.close(); } catch(IOException ignore) {} } 55 } 56 private class QuestionReceiver extends AsyncTask<Void,Void,String> { 57 @Override 58 protected String doInBackground(Void... aVoid) { 59 try { 60 Log.d("QuestionReceiver.doInBackground", "問題受信"); 61 BufferedReader r = manager.getReader(); 62 int linecount = Integer.parseInt(r.readLine()); 63 Log.d("QuestionReceiver.doInBackground", "linecount="+linecount); 64 if(linecount == 0) return null; 65 String text = ""; 66 for(int i=0; i<linecount; i++) text += r.readLine() + "\n"; 67 Log.d("QuestionReceiver.doInBackground", "text="+text); 68 return text; 69 } catch (IOException e) { 70 Log.e("QuestionReceiver.doInBackground", "問題受信異常", e); 71 e.printStackTrace(); 72 } 73 return null; 74 } 75 @Override 76 protected void onPostExecute(String text) { 77 Log.d("QuestionReceiver.onPostExecute", "text="+text); 78 if(text == null) { 79 finalAnswer.setText("終わります"); 80 finalAnswer.setOnClickListener(new View.OnClickListener() { 81 @Override 82 public void onClick(View v) { 83 Log.d("QuestionReceiver.onPostExecute", "finalAnswer.OnClick"); 84 manager.disconnect(); 85 ClientActivity.this.finish(); 86 } 87 }); 88 return; 89 } 90 Log.d("QuestionReceiver.onPostExecute", "問題表示"); 91 questionView.setText(text); 92 answerView.setText(""); 93 resultView.setText(""); 94 answerView.requestFocus(); 95 } 96 } 97 private class ResultReceiver extends AsyncTask<String,Object,String> { 98 @Override 99 protected String doInBackground(String... answers) { 100 String answer = answers[0]; 101 try { 102 Log.d("ResultReceiver.doInBackground", "回答送信 answer="+answer); 103 BufferedWriter w = manager.getWriter(); 104 w.write(answer + "\n"); 105 w.flush(); 106 Log.d("ResultReceiver.doInBackground", "判定受信"); 107 BufferedReader r = manager.getReader(); 108 return r.readLine(); 109 } catch(IOException e) { 110 Log.e("ResultReceiver.doInBackground", "異常", e); 111 e.printStackTrace(); 112 } 113 return null; 114 } 115 @Override 116 protected void onPostExecute(String result) { 117 Log.d("ResultReceiver.onPostExecute", "判定="+result); 118 if(result == null) return; 119 Log.d("ResultReceiver.onPostExecute", "判定表示"); 120 resultView.setText(result); 121 if(result.equalsIgnoreCase("OK")) { 122 Log.d("ResultReceiver.onPostExecute", "次問題"); 123 new QuestionReceiver().execute(); 124 } else { 125 Log.d("ResultReceiver.onPostExecute", "再回答"); 126 answerView.setText(""); 127 answerView.requestFocus(); 128 } 129 } 130 } 131}

xml(R.layout.activity_client.xml)

1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical" 7 tools:context=".ClientActivity"> 8 <TextView 9 android:id="@+id/question" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:textAppearance="@style/TextAppearance.AppCompat.Large" 13 android:text="問題文"/> 14 <EditText 15 android:id="@+id/answer" 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:textAppearance="@style/TextAppearance.AppCompat.Large" 19 android:text="回答欄"/> 20 <TextView 21 android:id="@+id/result" 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 android:textAppearance="@style/TextAppearance.AppCompat.Large" 25 android:text="結果"/> 26 <Button 27 android:id="@+id/finalAnswer" 28 android:layout_width="wrap_content" 29 android:layout_height="wrap_content" 30 android:text="回答送信"/> 31</LinearLayout>

投稿2019/01/30 08:37

編集2019/01/31 13:54
jimbe

総合スコア12646

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

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

jimbe

2019/01/30 16:57

すいません, やはりやっつけ仕事では動かないですね. コードを直していますが, 今度は編集で A01110_ERR_MSG004 と言われてしまい...これは大きすぎということでしょうか.
jimbe

2019/01/31 03:50

コードよりも, 2つのエミュレータで通信するという設定のほうで詰まっております.
shalllaugh

2019/01/31 05:29

すみません…!ありがとうございます!今からソースコードを見て勉強したいと思います!
jimbe

2019/01/31 13:21

実機とパソコン(telnet)でサーバ側が動作することは確認しました. 正常ルートのみです. 動かすと次のようなログが出ます. D/Server.run: s=Socket[address=/192.168.1.6,port=64727,localPort=8080] D/Server.run: accept() D/Questioner.doInBackground: 問題送信 linecount=3, text=2019年1月1日は何曜日? 1=月曜日, 2=火曜日, 3=水曜日 4=木曜日, 5=金曜日, 6=土曜日 D/Questioner.doInBackground: 回答受信 D/Questioner.doInBackground: answer=1 判定送信 result=NG D/Questioner.doInBackground: 回答受信 D/Questioner.doInBackground: answer=2 判定送信 result=OK D/Questioner.doInBackground: 問題送信 linecount=1, text=1+2=? D/Questioner.doInBackground: 回答受信 D/Questioner.doInBackground: answer=3 判定送信 result=OK D/Questioner.doInBackground: 終了送信
jimbe

2019/01/31 13:33

実機サーバ<->エミュレータクライアントでクライアント側も動作しました. 動かすと次のようなログが出ます. D/QuestionReceiver.doInBackground: 問題受信 D/ConnectionManager.connect: 接続 D/ConnectionManager.connect: 接続成功 D/QuestionReceiver.doInBackground: linecount=3 text=2019年1月1日は何曜日? 1=月曜日, 2=火曜日, 3=水曜日 4=木曜日, 5=金曜日, 6=土曜日 D/QuestionReceiver.onPostExecute: text=2019年1月1日は何曜日? 1=月曜日, 2=火曜日, 3=水曜日 4=木曜日, 5=金曜日, 6=土曜日 問題表示 D/ResultReceiver.doInBackground: 回答送信 answer=1 D/ResultReceiver.doInBackground: 判定受信 D/ResultReceiver.onPostExecute: 判定=NG 判定表示 再回答 D/ResultReceiver.doInBackground: 回答送信 answer=2 D/ResultReceiver.doInBackground: 判定受信 D/ResultReceiver.onPostExecute: 判定=OK 判定表示 D/ResultReceiver.onPostExecute: 次問題 D/QuestionReceiver.doInBackground: 問題受信 D/QuestionReceiver.doInBackground: linecount=1 text=1+2=? D/QuestionReceiver.onPostExecute: text=1+2=? 問題表示 D/ResultReceiver.doInBackground: 回答送信 answer=3 D/ResultReceiver.doInBackground: 判定受信 D/ResultReceiver.onPostExecute: 判定=OK D/ResultReceiver.onPostExecute: 判定表示 次問題 D/QuestionReceiver.doInBackground: 問題受信 D/QuestionReceiver.doInBackground: linecount=0 D/QuestionReceiver.onPostExecute: text=null D/QuestionReceiver.onPostExecute: finalAnswer.OnClick どちらもユーザーの回答は 1問目 "1"(間違い) 再回答 "2"(正解) 2問目 "3"(正解) で, 最期に "終わります" と表記が変わった finalAnser を押してクライアントは終了です. サーバはずっとクライアントを待ち続けますので, 適当に停止させてください. サーバ側に画面を作って操作できるようにしても良いかもしれません.
shalllaugh

2019/02/03 06:57

こんなに丁寧にしてくださって、ありがとうございます…!参考にさせていただきます!
jimbe

2019/02/03 08:19

通信するプログラムの場合はあらゆる所で切断される可能性がありますが, ご提示したコードは, 特にクライアント側は何もしていません. クライアントを再起動するしかありません. これを例えば回答の送信時に切断されたら(「クライアントを再起動したら」でも同じかもしれません)再起動後に同じ質問から続けられるようにする等の救済をする等が必要かもしれません. 頑張って下さい.
guest

0

ベストアンサー

前回の質問から察するに、このようにすべきだったのだろうと思います。

java

1 String rs = "NG"; 2 ServerSocket ss = null; 3 Socket ws = null; 4 BufferedReader br = null; 5 6 /* - 解答文字列受信 - */ 7 try { 8 ss = new ServerSocket(8181); 9 boolean loop = true; 10 11 /* ここをループ構造にすることが肝 */ 12 while (loop) { 13 /* - 受信待機 - */ 14 ws = ss.accept(); 15 16 /* - 受信文字列格納 - */ 17 br = new BufferedReader(new InputStreamReader( 18 ws.getInputStream())); 19 rs = br.readLine(); 20 21 /* 正解ならばループから脱出する */ 22 if (rs.equals("正解")) { 23 loop = false; 24 } 25 26 /* - ソケットクローズ - */ 27 br.close(); 28 ws.close(); 29 } 30 } catch (IOException e) { 31 e.printStackTrace(); 32 } finally { 33 try { 34 if (br != null) { 35 br.close(); 36 } 37 38 if (ws != null) { 39 ws.close(); 40 } 41 42 if (ss != null) { 43 ss.close(); 44 } 45 } catch (IOException e) { 46 e.printStackTrace(); 47 } 48 }

ここでポイントになるのは、サーバーソケットを生成した後の処理をループ構造にするということです。何かしらの解答を受信して処理を行った後、サーバーソケットを即座にcloseしてしまっては、続けて解答を受け取ることができません。ここでcloseせずにループして、再びacceptで受信待機に戻します。これによって、解答側のプログラムで同じポートに送信したものを何度も受け取ることができるようになります。正解を得られたらそこで終了でしょうから、ここで初めてサーバーソケットをcloseするわけです。

投稿2019/01/20 09:12

編集2019/01/20 12:33
keicha_hrs

総合スコア6768

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

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

shalllaugh

2019/01/20 09:43

なるほど、そういう風に書くんですね!丁寧に教えていただきありがとうございます。ちなみに、acceptで生成したソケットのcloseをfinallyで行わないのはなぜなのでしょうか?逆にその他のソケットやストリームをfinallyでcloseしているのはなぜなのでしょうか?
keicha_hrs

2019/01/20 10:07 編集

> acceptで生成したソケットのcloseをfinallyで行わないのはなぜなのでしょうか? ごめんなさい、チョンボです。よく確認せず記述したので書き損じました。 > 逆にその他のソケットやストリームをfinallyでcloseしているのはなぜなのでしょうか? 例外を発生するAPIが至るところにあるため、どこで例外が飛んでも「閉じ忘れ」がないようにするためです。
shalllaugh

2019/01/20 12:10

あ、そうなのですね。じゃあtryの中で記述している部分は消してしまって大丈夫ってことですね。ありがとうございます。
keicha_hrs

2019/01/20 12:37

またコードにミスがあったので直しています(大勢に影響はなさそうだけど)。 > tryの中で記述している部分は消してしまって大丈夫 これはどちらのtryのことを仰っているのでしょうか。whileループ脱出後にss.close()するように追加して(これを忘れてはいけない)、finallyブロックの中身は無しにしても、一応動くとは思います。エラー対処的にどうなのかとは思うけど。
shalllaugh

2019/01/20 13:26

最初のtryのことを言ってました。finallyでcloseするからwhile後は消して良い、ではなくfinallyではcloseしなくていいからwhile後は必ずしなければならないってことですかね?
keicha_hrs

2019/01/20 14:00

よくわからないので、私の回答をベースにして「このように書けば良いと考えた」ものを質問の追記として記述していただけませんか。この程度なら文字数制限にはかからないでしょう。
shalllaugh

2019/01/20 14:08

わかりました、書きます。
keicha_hrs

2019/01/20 14:54

acSocket.close()はwhileループの最後に入れてください。そうしないと、次にaccept()を呼んだときにエラーで落ちます。また、brもreadLine()以降にclose()してください。なお、isrはbrのclose()によって閉じられるので、明示的に閉じる必要はありません。 それから、acSocketはfinallyの中でもclose()してください。acSocketが開かれたまま何かしらのエラーが発生してcatch→finallyと流れたときに、開かれたままになってしまうのを防ぐために入れます。 acSocketをcloseする箇所が複数あることが無駄な処理に見えるのかもしれませんが、accept()と対にclose()しなければならないこと、不意のエラーで開かれっぱなしになっているものを閉じなければならないことを考えると、どうしても2箇所必要になります(エラー処理を考えない設計ならば別ですが)。
shalllaugh

2019/01/30 05:09

ご指摘頂いた点を修正したところ、解答の複数回受信が出来ました。ありがとうございました。
keicha_hrs

2019/01/30 13:30

Androidのようなプラットフォーム上ではなく、コマンドプロンプトのような端末上で動くようなTCP通信のプログラムを書いたことがあるでしょうか?サーバー側、クライアント側とも、数十行程度で書けるごく簡単なものです。それを知っているかどうかで、今回のような応用でも随分違ってくると思うのですが。理屈も知らず、「たまたま動く」ところまでカットアンドトライを繰り返す手法は最悪です。
shalllaugh

2019/01/31 05:30

ご指摘痛み入ります。コマンドプロンプトで動作するシステムの開発経験はなく、今回Androidで初めてTCP通信のシステムを開発しました。通信の仕組み等自分なりに勉強はしましたが、足りなかったみたいです。ありがとうございました。
退会済みユーザー

退会済みユーザー

2019/02/03 07:14

ちなみに、オートクローズをちゃんと使えば 半分以上削減できるじゃろ
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問