回答編集履歴

8

サーバ側不要setContentView削除

2019/01/31 13:54

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  super.onCreate(savedInstanceState);
26
26
 
27
- setContentView(R.layout.activity_server);
27
+ //setContentView(R.layout.activity_server);
28
28
 
29
29
  try {
30
30
 

7

クライアントレイアウト追加

2019/01/31 13:54

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -475,3 +475,69 @@
475
475
  }
476
476
 
477
477
  ```
478
+
479
+ ```xml(R.layout.activity_client.xml)
480
+
481
+ <?xml version="1.0" encoding="utf-8"?>
482
+
483
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
484
+
485
+ xmlns:tools="http://schemas.android.com/tools"
486
+
487
+ android:layout_width="match_parent"
488
+
489
+ android:layout_height="match_parent"
490
+
491
+ android:orientation="vertical"
492
+
493
+ tools:context=".ClientActivity">
494
+
495
+ <TextView
496
+
497
+ android:id="@+id/question"
498
+
499
+ android:layout_width="match_parent"
500
+
501
+ android:layout_height="wrap_content"
502
+
503
+ android:textAppearance="@style/TextAppearance.AppCompat.Large"
504
+
505
+ android:text="問題文"/>
506
+
507
+ <EditText
508
+
509
+ android:id="@+id/answer"
510
+
511
+ android:layout_width="match_parent"
512
+
513
+ android:layout_height="wrap_content"
514
+
515
+ android:textAppearance="@style/TextAppearance.AppCompat.Large"
516
+
517
+ android:text="回答欄"/>
518
+
519
+ <TextView
520
+
521
+ android:id="@+id/result"
522
+
523
+ android:layout_width="match_parent"
524
+
525
+ android:layout_height="wrap_content"
526
+
527
+ android:textAppearance="@style/TextAppearance.AppCompat.Large"
528
+
529
+ android:text="結果"/>
530
+
531
+ <Button
532
+
533
+ android:id="@+id/finalAnswer"
534
+
535
+ android:layout_width="wrap_content"
536
+
537
+ android:layout_height="wrap_content"
538
+
539
+ android:text="回答送信"/>
540
+
541
+ </LinearLayout>
542
+
543
+ ```

6

サーバ側コード修正, 実機サーバ<->telnetクライアントで簡単な動作確認.

2019/01/31 13:51

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -18,462 +18,460 @@
18
18
 
19
19
  public class ServerActivity extends AppCompatActivity {
20
20
 
21
- @Override
21
+ @Override
22
-
22
+
23
- protected void onCreate(Bundle savedInstanceState) {
23
+ protected void onCreate(Bundle savedInstanceState) {
24
-
24
+
25
- super.onCreate(savedInstanceState);
25
+ super.onCreate(savedInstanceState);
26
-
26
+
27
- setContentView(R.layout.activity_server);
27
+ setContentView(R.layout.activity_server);
28
+
29
+ try {
30
+
31
+ new Thread(new Server("0.0.0.0",8080)).start();
32
+
33
+ } catch (IOException e) {
34
+
35
+ e.printStackTrace();
36
+
37
+ }
38
+
39
+ }
40
+
41
+ private class Server implements Runnable {
42
+
43
+ private String host;
44
+
45
+ private int port;
46
+
47
+ Server(String host, int port) throws IOException {
48
+
49
+ this.host = host;
50
+
51
+ this.port = port;
52
+
53
+ }
54
+
55
+ @Override
56
+
57
+ public void run() {
58
+
59
+ Log.d("Server", "アドレス="+host+", ポート="+port);
60
+
61
+ ServerSocket ss = null;
62
+
63
+ try {
64
+
65
+ ss = new ServerSocket();
66
+
67
+ ss.bind(new InetSocketAddress(host, port));
68
+
69
+ while(true) {
70
+
71
+ Log.d("Server.run", "accept()");
72
+
73
+ Socket s = ss.accept();
74
+
75
+ Log.d("Server.run", "s="+s);
76
+
77
+ new Questioner().execute(s);
78
+
79
+ }
80
+
81
+ } catch (IOException e) {
82
+
83
+ Log.e("Server.run", "IOException", e);
84
+
85
+ } finally {
86
+
87
+ if(ss != null) try { ss.close(); } catch (IOException ignore) {}
88
+
89
+ }
90
+
91
+ }
92
+
93
+ }
94
+
95
+ private class Questioner extends AsyncTask<Object, Object, String> {
96
+
97
+ @Override
98
+
99
+ protected String doInBackground(Object... objects) {
100
+
101
+ Socket s = (Socket)objects[0]; //パラメータ1つめは Socket.
102
+
103
+ try {
104
+
105
+ BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
106
+
107
+ BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
108
+
109
+ Question q;
110
+
111
+ for(int number=1; (q = createQuestion(number)) != null; number++) {
112
+
113
+ Log.d("Questioner.doInBackground", "問題送信 linecount="+q.linecount+", text="+q.text);
114
+
115
+ w.write(q.linecount+"\n");
116
+
117
+ w.write(q.text);
118
+
119
+ w.flush();
120
+
121
+ String result;
122
+
123
+ do {
124
+
125
+ Log.d("Questioner.doInBackground", "回答受信");
126
+
127
+ String answer = r.readLine();
128
+
129
+ Log.d("Questioner.doInBackground", "answer="+answer);
130
+
131
+ if(answer == null) return null;
132
+
133
+ result = answer.equals(q.correctAnswer) ? "OK" : "NG";
134
+
135
+ Log.d("Questioner.doInBackground", "判定送信 result="+result);
136
+
137
+ w.write(result + "\n");
138
+
139
+ w.flush();
140
+
141
+ } while (result.equals("NG"));
142
+
143
+ }
144
+
145
+ Log.d("Questioner.doInBackground", "終了送信");
146
+
147
+ w.write("0\n");
148
+
149
+ w.flush();
150
+
151
+ } catch (IOException e) {
152
+
153
+ Log.e("Questioner.doInBackground", "異常", e);
154
+
155
+ } finally {
156
+
157
+ try { s.close(); } catch(IOException ignore) {}
158
+
159
+ }
160
+
161
+ return null;
162
+
163
+ }
164
+
165
+ private class Question {
166
+
167
+ final int linecount;
168
+
169
+ final String text;
170
+
171
+ final String correctAnswer;
172
+
173
+ Question(int linecount, String text, String correctAnswer) {
174
+
175
+ this.linecount = linecount;
176
+
177
+ this.text = text;
178
+
179
+ this.correctAnswer = correctAnswer;
180
+
181
+ }
182
+
183
+ }
184
+
185
+ private Question createQuestion(int questionNumber) {
186
+
187
+ switch(questionNumber) {
188
+
189
+ case 1: return new Question(3,
190
+
191
+ "2019年1月1日は何曜日?\n1=月曜日, 2=火曜日, 3=水曜日\n4=木曜日, 5=金曜日, 6=土曜日\n",
192
+
193
+ "2");
194
+
195
+ case 2: return new Question(1,
196
+
197
+ "1+2=?\n",
198
+
199
+ "3");
200
+
201
+ }
202
+
203
+ return null;
204
+
205
+ }
206
+
207
+ }
208
+
209
+ }
210
+
211
+ ```
212
+
213
+ ```java
214
+
215
+ public class ClientActivity extends AppCompatActivity {
216
+
217
+ private TextView questionView;
218
+
219
+ private EditText answerView;
220
+
221
+ private TextView resultView;
222
+
223
+ private Button finalAnswer;
224
+
225
+ @Override
226
+
227
+ protected void onCreate(Bundle savedInstanceState) {
228
+
229
+ super.onCreate(savedInstanceState);
230
+
231
+ setContentView(R.layout.activity_client);
232
+
233
+ questionView = (TextView)findViewById(R.id.question);
234
+
235
+ answerView = (EditText)findViewById(R.id.answer);
236
+
237
+ resultView = (TextView)findViewById(R.id.result);
238
+
239
+ finalAnswer = (Button)findViewById(R.id.finalAnswer);
240
+
241
+ finalAnswer.setOnClickListener(new View.OnClickListener() {
242
+
243
+ @Override
244
+
245
+ public void onClick(View v) {
246
+
247
+ String answer = answerView.getText().toString();
248
+
249
+ if(answer.length() == 0) return;
250
+
251
+ new ResultReceiver().execute(answer);
252
+
253
+ }
254
+
255
+ });
256
+
257
+ manager = new ConnectionManager("10.0.2.2", 8181);
258
+
259
+ new QuestionReceiver().execute();
260
+
261
+ }
262
+
263
+ private ConnectionManager manager;
264
+
265
+ private class ConnectionManager {
266
+
267
+ private String host;
268
+
269
+ private int port;
270
+
271
+ private Socket s;
272
+
273
+ private BufferedWriter w;
274
+
275
+ private BufferedReader r;
276
+
277
+ ConnectionManager(String host, int port) {
278
+
279
+ this.host = host;
280
+
281
+ this.port = port;
282
+
283
+ }
284
+
285
+ void connect() throws IOException {
286
+
287
+ if(s == null) {
288
+
289
+ Log.d("ConnectionManager.connect", "接続");
290
+
291
+ s = new Socket(host, port);
28
292
 
29
293
  try {
30
294
 
295
+ w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
296
+
31
- new Thread(new Server(8080)).start();
297
+ r = new BufferedReader(new InputStreamReader(s.getInputStream()));
298
+
32
-
299
+ Log.d("ConnectionManager.connect", "接続成功");
300
+
33
- } catch (IOException e) {
301
+ } catch(IOException e) {
302
+
34
-
303
+ Log.e("ConnectionManager.connect", "接続失敗", e);
304
+
305
+ try { s.close(); } catch(IOException ignore) {}
306
+
35
- e.printStackTrace();
307
+ s = null; w = null; r = null;
308
+
309
+ throw e;
36
310
 
37
311
  }
38
312
 
39
- }
40
-
41
- //サーバ. 延々と受付待ちです.
42
-
43
- private class Server implements Runnable {
44
-
45
- ServerSocket ss;
46
-
47
- Server(int port) throws IOException {
48
-
49
- ss = new ServerSocket(port);
50
-
51
- }
52
-
53
- @Override
54
-
55
- public void run() {
56
-
57
- try {
58
-
59
- while(true) {//延々と付待ち
60
-
61
- Socket s = ss.accept();//サーバは受付だけ
62
-
63
- new Questioner().execute(s);//受付したら, 後は専用スレッドに任せます.
64
-
65
- }
66
-
67
- } catch (IOException e) {
68
-
69
- e.printStackTrace();
70
-
71
- } finally {
72
-
73
- try { ss.close(); } catch (IOException ignore) {}
74
-
75
- }
76
-
77
- }
78
-
79
- }
80
-
81
- //クライアントと会話する質問者. パラメータの Socket は既にクライアントと繋がっています.
82
-
83
- private class Questioner extends AsyncTask<Object, Object, String> {
84
-
85
- @Override
86
-
87
- protected String doInBackground(Object... objects) {
88
-
89
- Socket s = (Socket)objects[0];//パラメータ1つめは Socket.
90
-
91
- try {
92
-
93
- BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
94
-
95
- BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
96
-
97
- Question q;
98
-
99
- for(int number=1; (q = createQuestion(number)) != null; number++) { //問題が無くなるまで繰り返す
100
-
101
- //まずクライアントに問題を送ります. まず行数を送り, 次にその行数文の問題文を送ります. 改行を忘れないでください.
102
-
103
- //これ以降のプロトコルは仕様次第です.
104
-
105
- w.write(q.linecount+"\n");
106
-
107
- w.write(q.text);
108
-
109
- w.flush(); //flushしないと, バッファに入るだけで送られていない場合があります.
110
-
111
- String result;
112
-
113
- do {
114
-
115
- //問題を送るとクライアントはそれを表示して入力を待ち, 入力されたら数字を1行として送ってくることにしました.
116
-
117
- //なのでそれを待ちます.
118
-
119
- String answer = r.readLine(); //行は改行で終わるため, このメソッドが使えます.
120
-
121
- if(answer == null) return null; //切断されたらこちらも終わります. 2重ループのため return で一気に抜けます
122
-
123
- //答え合わせ.
124
-
125
- if (answer.equals(q.correctAnswer)) {
126
-
127
- result = "OK";
128
-
129
- } else {
130
-
131
- result = "NG";
132
-
133
- }
134
-
135
- //結果を一行でクライアントに送ります. クライアントはこれを待っているはずです.
136
-
137
- w.write(result + "\n");
138
-
139
- w.flush();
140
-
141
- } while (result.equals("NG")); //答えが間違っていた場合再び回答待ちになります.
142
-
143
- }
144
-
145
- w.write("0\n"); //クライアントは次の問題を待っているはずですが, 行数 0 を送って終わりを通知します.
146
-
147
- w.flush();
148
-
149
-
150
-
151
- } catch (IOException e) {
152
-
153
- e.printStackTrace();
154
-
155
- } finally {
156
-
157
- try { s.close(); } catch(IOException ignore) {}
158
-
159
- }
160
-
161
- return null;
162
-
163
- }
164
-
165
- //この辺りは仕様やプロトコルによって決めてください.
166
-
167
- private class Question {
168
-
169
- final int linecount; //text の行数. 出来れば改行の数を数える等で自動で値を求めたい所です
170
-
171
- final String text; //問題文
172
-
173
- final String correctAnswer; //正解
174
-
175
- Question(int linecount, String text, String correctAnswer) {
176
-
177
- this.linecount = linecount;
178
-
179
- this.text = text;
180
-
181
- this.correctAnswer = correctAnswer;
182
-
183
- }
184
-
185
- }
186
-
187
- private Question createQuestion(int questionNumber) {
188
-
189
- switch(questionNumber) {
190
-
191
- case 1: return new Question(3, //行数
192
-
193
- "2019年1月1日は何曜日?\n1=月曜日, 2=火曜日, 3=水曜日\n4=木曜日, 5=金曜日, 6=土曜日\n",
194
-
195
- "2"); //正解
196
-
197
- case 2: return new Question(1,
198
-
199
- "1+2=?\n",
200
-
201
- "3");
202
-
203
- }
204
-
205
- return null; //問題が無くなった.
206
-
207
- }
208
-
209
- }
313
+ }
314
+
315
+ }
316
+
317
+ BufferedReader getReader() throws IOException { connect(); return r; }
318
+
319
+ BufferedWriter getWriter() throws IOException { connect(); return w; }
320
+
321
+ void disconnect() { if(s == null) try { s.close(); } catch(IOException ignore) {} }
322
+
323
+ }
324
+
325
+ private class QuestionReceiver extends AsyncTask<Void,Void,String> {
326
+
327
+ @Override
328
+
329
+ protected String doInBackground(Void... aVoid) {
330
+
331
+ try {
332
+
333
+ Log.d("QuestionReceiver.doInBackground", "問題信");
334
+
335
+ BufferedReader r = manager.getReader();
336
+
337
+ int linecount = Integer.parseInt(r.readLine());
338
+
339
+ Log.d("QuestionReceiver.doInBackground", "linecount="+linecount);
340
+
341
+ if(linecount == 0) return null;
342
+
343
+ String text = "";
344
+
345
+ for(int i=0; i<linecount; i++) text += r.readLine() + "\n";
346
+
347
+ Log.d("QuestionReceiver.doInBackground", "text="+text);
348
+
349
+ return text;
350
+
351
+ } catch (IOException e) {
352
+
353
+ Log.e("QuestionReceiver.doInBackground", "問題受信異常", e);
354
+
355
+ e.printStackTrace();
356
+
357
+ }
358
+
359
+ return null;
360
+
361
+ }
362
+
363
+ @Override
364
+
365
+ protected void onPostExecute(String text) {
366
+
367
+ Log.d("QuestionReceiver.onPostExecute", "text="+text);
368
+
369
+ if(text == null) {
370
+
371
+ finalAnswer.setText("終わります");
372
+
373
+ finalAnswer.setOnClickListener(new View.OnClickListener() {
374
+
375
+ @Override
376
+
377
+ public void onClick(View v) {
378
+
379
+ Log.d("QuestionReceiver.onPostExecute", "finalAnswer.OnClick");
380
+
381
+ manager.disconnect();
382
+
383
+ ClientActivity.this.finish();
384
+
385
+ }
386
+
387
+ });
388
+
389
+ return;
390
+
391
+ }
392
+
393
+ Log.d("QuestionReceiver.onPostExecute", "問題表示");
394
+
395
+ questionView.setText(text);
396
+
397
+ answerView.setText("");
398
+
399
+ resultView.setText("");
400
+
401
+ answerView.requestFocus();
402
+
403
+ }
404
+
405
+ }
406
+
407
+ private class ResultReceiver extends AsyncTask<String,Object,String> {
408
+
409
+ @Override
410
+
411
+ protected String doInBackground(String... answers) {
412
+
413
+ String answer = answers[0];
414
+
415
+ try {
416
+
417
+ Log.d("ResultReceiver.doInBackground", "回答送信 answer="+answer);
418
+
419
+ BufferedWriter w = manager.getWriter();
420
+
421
+ w.write(answer + "\n");
422
+
423
+ w.flush();
424
+
425
+ Log.d("ResultReceiver.doInBackground", "判定受信");
426
+
427
+ BufferedReader r = manager.getReader();
428
+
429
+ return r.readLine();
430
+
431
+ } catch(IOException e) {
432
+
433
+ Log.e("ResultReceiver.doInBackground", "異常", e);
434
+
435
+ e.printStackTrace();
436
+
437
+ }
438
+
439
+ return null;
440
+
441
+ }
442
+
443
+ @Override
444
+
445
+ protected void onPostExecute(String result) {
446
+
447
+ Log.d("ResultReceiver.onPostExecute", "判定="+result);
448
+
449
+ if(result == null) return;
450
+
451
+ Log.d("ResultReceiver.onPostExecute", "判定表示");
452
+
453
+ resultView.setText(result);
454
+
455
+ if(result.equalsIgnoreCase("OK")) {
456
+
457
+ Log.d("ResultReceiver.onPostExecute", "次問題");
458
+
459
+ new QuestionReceiver().execute();
460
+
461
+ } else {
462
+
463
+ Log.d("ResultReceiver.onPostExecute", "再回答");
464
+
465
+ answerView.setText("");
466
+
467
+ answerView.requestFocus();
468
+
469
+ }
470
+
471
+ }
472
+
473
+ }
210
474
 
211
475
  }
212
476
 
213
477
  ```
214
-
215
- ```java
216
-
217
- public class ClientActivity extends AppCompatActivity {
218
-
219
- private TextView questionView;
220
-
221
- private EditText answerView;
222
-
223
- private TextView resultView;
224
-
225
- private Button finalAnswer;
226
-
227
- @Override
228
-
229
- protected void onCreate(Bundle savedInstanceState) {
230
-
231
- super.onCreate(savedInstanceState);
232
-
233
- setContentView(R.layout.activity_client);
234
-
235
- questionView = (TextView)findViewById(R.id.question);
236
-
237
- answerView = (EditText)findViewById(R.id.answer);
238
-
239
- resultView = (TextView)findViewById(R.id.result);
240
-
241
- finalAnswer = (Button)findViewById(R.id.finalAnswer);
242
-
243
- finalAnswer.setOnClickListener(new View.OnClickListener() {
244
-
245
- @Override
246
-
247
- public void onClick(View v) {
248
-
249
- String answer = answerView.getText().toString();
250
-
251
- if(answer.length() == 0) return;
252
-
253
- new ResultReceiver().execute(answer);
254
-
255
- }
256
-
257
- });
258
-
259
- manager = new ConnectionManager("10.0.2.2", 8181);
260
-
261
- new QuestionReceiver().execute();
262
-
263
- }
264
-
265
- private ConnectionManager manager;
266
-
267
- private class ConnectionManager {
268
-
269
- private String host;
270
-
271
- private int port;
272
-
273
- private Socket s;
274
-
275
- private BufferedWriter w;
276
-
277
- private BufferedReader r;
278
-
279
- ConnectionManager(String host, int port) {
280
-
281
- this.host = host;
282
-
283
- this.port = port;
284
-
285
- }
286
-
287
- void connect() throws IOException {
288
-
289
- if(s == null) {
290
-
291
- Log.d("ConnectionManager.connect", "接続");
292
-
293
- s = new Socket(host, port);
294
-
295
- try {
296
-
297
- w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
298
-
299
- r = new BufferedReader(new InputStreamReader(s.getInputStream()));
300
-
301
- Log.d("ConnectionManager.connect", "接続成功");
302
-
303
- } catch(IOException e) {
304
-
305
- Log.e("ConnectionManager.connect", "接続失敗", e);
306
-
307
- try { s.close(); } catch(IOException ignore) {}
308
-
309
- s = null; w = null; r = null;
310
-
311
- throw e;
312
-
313
- }
314
-
315
- }
316
-
317
- }
318
-
319
- BufferedReader getReader() throws IOException { connect(); return r; }
320
-
321
- BufferedWriter getWriter() throws IOException { connect(); return w; }
322
-
323
- void disconnect() { if(s == null) try { s.close(); } catch(IOException ignore) {} }
324
-
325
- }
326
-
327
- private class QuestionReceiver extends AsyncTask<Void,Void,String> {
328
-
329
- @Override
330
-
331
- protected String doInBackground(Void... aVoid) {
332
-
333
- try {
334
-
335
- Log.d("QuestionReceiver.doInBackground", "問題受信");
336
-
337
- BufferedReader r = manager.getReader();
338
-
339
- int linecount = Integer.parseInt(r.readLine());
340
-
341
- Log.d("QuestionReceiver.doInBackground", "linecount="+linecount);
342
-
343
- if(linecount == 0) return null;
344
-
345
- String text = "";
346
-
347
- for(int i=0; i<linecount; i++) text += r.readLine() + "\n";
348
-
349
- Log.d("QuestionReceiver.doInBackground", "text="+text);
350
-
351
- return text;
352
-
353
- } catch (IOException e) {
354
-
355
- Log.e("QuestionReceiver.doInBackground", "問題受信異常", e);
356
-
357
- e.printStackTrace();
358
-
359
- }
360
-
361
- return null;
362
-
363
- }
364
-
365
- @Override
366
-
367
- protected void onPostExecute(String text) {
368
-
369
- Log.d("QuestionReceiver.onPostExecute", "text="+text);
370
-
371
- if(text == null) {
372
-
373
- finalAnswer.setText("終わります");
374
-
375
- finalAnswer.setOnClickListener(new View.OnClickListener() {
376
-
377
- @Override
378
-
379
- public void onClick(View v) {
380
-
381
- Log.d("QuestionReceiver.onPostExecute", "finalAnswer.OnClick");
382
-
383
- manager.disconnect();
384
-
385
- ClientActivity.this.finish();
386
-
387
- }
388
-
389
- });
390
-
391
- return;
392
-
393
- }
394
-
395
- Log.d("QuestionReceiver.onPostExecute", "問題表示");
396
-
397
- questionView.setText(text);
398
-
399
- answerView.setText("");
400
-
401
- resultView.setText("");
402
-
403
- answerView.requestFocus();
404
-
405
- }
406
-
407
- }
408
-
409
- private class ResultReceiver extends AsyncTask<String,Object,String> {
410
-
411
- @Override
412
-
413
- protected String doInBackground(String... answers) {
414
-
415
- String answer = answers[0];
416
-
417
- try {
418
-
419
- Log.d("ResultReceiver.doInBackground", "回答送信 answer="+answer);
420
-
421
- BufferedWriter w = manager.getWriter();
422
-
423
- w.write(answer + "\n");
424
-
425
- w.flush();
426
-
427
- Log.d("ResultReceiver.doInBackground", "判定受信");
428
-
429
- BufferedReader r = manager.getReader();
430
-
431
- return r.readLine();
432
-
433
- } catch(IOException e) {
434
-
435
- Log.e("ResultReceiver.doInBackground", "異常", e);
436
-
437
- e.printStackTrace();
438
-
439
- }
440
-
441
- return null;
442
-
443
- }
444
-
445
- @Override
446
-
447
- protected void onPostExecute(String result) {
448
-
449
- Log.d("ResultReceiver.onPostExecute", "判定="+result);
450
-
451
- if(result == null) return;
452
-
453
- Log.d("ResultReceiver.onPostExecute", "判定表示");
454
-
455
- resultView.setText(result);
456
-
457
- if(result.equalsIgnoreCase("OK")) {
458
-
459
- Log.d("ResultReceiver.onPostExecute", "次問題");
460
-
461
- new QuestionReceiver().execute();
462
-
463
- } else {
464
-
465
- Log.d("ResultReceiver.onPostExecute", "再回答");
466
-
467
- answerView.setText("");
468
-
469
- answerView.requestFocus();
470
-
471
- }
472
-
473
- }
474
-
475
- }
476
-
477
- }
478
-
479
- ```

5

コードに合わせて説明を変更

2019/01/31 13:04

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  サーバ側は使っていません.
8
8
 
9
- なるべく説明を入れてみましたが... あくまで参考ということでお願いします.
9
+ 説明を入れてみましたが, 修正すると書き込みが大きすぎになるようで消さざるをえませんでした. あくまで参考ということでお願いします.
10
10
 
11
11
  流れを図にしてみました.
12
12
 
@@ -238,8 +238,6 @@
238
238
 
239
239
  resultView = (TextView)findViewById(R.id.result);
240
240
 
241
- //回答欄に入力したらボタンを押し, サーバに送信
242
-
243
241
  finalAnswer = (Button)findViewById(R.id.finalAnswer);
244
242
 
245
243
  finalAnswer.setOnClickListener(new View.OnClickListener() {
@@ -250,7 +248,7 @@
250
248
 
251
249
  String answer = answerView.getText().toString();
252
250
 
253
- if(answer.length() == 0) return;//入ってなかったら無視
251
+ if(answer.length() == 0) return;
254
252
 
255
253
  new ResultReceiver().execute(answer);
256
254
 
@@ -258,9 +256,9 @@
258
256
 
259
257
  });
260
258
 
261
- manager = new ConnectionManager("10.0.2.2", 8181);//これはエミュレータでの設定(telnet localhost 5554 > redir add tcp:8080:8181 後)
259
+ manager = new ConnectionManager("10.0.2.2", 8181);
262
-
260
+
263
- new QuestionReceiver().execute();//最初の問題を受信, 表示して回答を待ちます.
261
+ new QuestionReceiver().execute();
264
262
 
265
263
  }
266
264
 
@@ -290,7 +288,7 @@
290
288
 
291
289
  if(s == null) {
292
290
 
293
- Log.d("ClientActivity.ConnectionManager.connect", "接続");
291
+ Log.d("ConnectionManager.connect", "接続");
294
292
 
295
293
  s = new Socket(host, port);
296
294
 
@@ -300,11 +298,11 @@
300
298
 
301
299
  r = new BufferedReader(new InputStreamReader(s.getInputStream()));
302
300
 
303
- Log.d("ClientActivity.ConnectionManager.connect", "接続成功");
301
+ Log.d("ConnectionManager.connect", "接続成功");
304
302
 
305
303
  } catch(IOException e) {
306
304
 
307
- Log.e("ClientActivity.ConnectionManager.connect", "接続失敗", e);
305
+ Log.e("ConnectionManager.connect", "接続失敗", e);
308
306
 
309
307
  try { s.close(); } catch(IOException ignore) {}
310
308
 
@@ -334,13 +332,13 @@
334
332
 
335
333
  try {
336
334
 
337
- Log.d("ClientActivity.QuestionReceiver.doInBackground", "問題受信");
335
+ Log.d("QuestionReceiver.doInBackground", "問題受信");
338
336
 
339
337
  BufferedReader r = manager.getReader();
340
338
 
341
339
  int linecount = Integer.parseInt(r.readLine());
342
340
 
343
- Log.d("ClientActivity.QuestionReceiver.doInBackground", "linecount="+linecount);
341
+ Log.d("QuestionReceiver.doInBackground", "linecount="+linecount);
344
342
 
345
343
  if(linecount == 0) return null;
346
344
 
@@ -348,13 +346,13 @@
348
346
 
349
347
  for(int i=0; i<linecount; i++) text += r.readLine() + "\n";
350
348
 
351
- Log.d("ClientActivity.QuestionReceiver.doInBackground", "text="+text);
349
+ Log.d("QuestionReceiver.doInBackground", "text="+text);
352
350
 
353
351
  return text;
354
352
 
355
353
  } catch (IOException e) {
356
354
 
357
- Log.e("ClientActivity.QuestionReceiver.doInBackground", "問題受信異常", e);
355
+ Log.e("QuestionReceiver.doInBackground", "問題受信異常", e);
358
356
 
359
357
  e.printStackTrace();
360
358
 
@@ -368,7 +366,7 @@
368
366
 
369
367
  protected void onPostExecute(String text) {
370
368
 
371
- Log.d("ClientActivity.QuestionReceiver.onPostExecute", "text="+text);
369
+ Log.d("QuestionReceiver.onPostExecute", "text="+text);
372
370
 
373
371
  if(text == null) {
374
372
 
@@ -380,7 +378,7 @@
380
378
 
381
379
  public void onClick(View v) {
382
380
 
383
- Log.d("ClientActivity.QuestionReceiver.onPostExecute", "finalAnswer.OnClick");
381
+ Log.d("QuestionReceiver.onPostExecute", "finalAnswer.OnClick");
384
382
 
385
383
  manager.disconnect();
386
384
 
@@ -394,7 +392,7 @@
394
392
 
395
393
  }
396
394
 
397
- Log.d("ClientActivity.QuestionReceiver.onPostExecute", "問題表示");
395
+ Log.d("QuestionReceiver.onPostExecute", "問題表示");
398
396
 
399
397
  questionView.setText(text);
400
398
 
@@ -418,7 +416,7 @@
418
416
 
419
417
  try {
420
418
 
421
- Log.d("ClientActivity.ResultReceiver.doInBackground", "回答送信 answer="+answer);
419
+ Log.d("ResultReceiver.doInBackground", "回答送信 answer="+answer);
422
420
 
423
421
  BufferedWriter w = manager.getWriter();
424
422
 
@@ -426,7 +424,7 @@
426
424
 
427
425
  w.flush();
428
426
 
429
- Log.d("ClientActivity.ResultReceiver.doInBackground", "判定受信");
427
+ Log.d("ResultReceiver.doInBackground", "判定受信");
430
428
 
431
429
  BufferedReader r = manager.getReader();
432
430
 
@@ -434,7 +432,7 @@
434
432
 
435
433
  } catch(IOException e) {
436
434
 
437
- Log.e("ClientActivity.ResultReceiver.doInBackground", "異常", e);
435
+ Log.e("ResultReceiver.doInBackground", "異常", e);
438
436
 
439
437
  e.printStackTrace();
440
438
 
@@ -448,23 +446,23 @@
448
446
 
449
447
  protected void onPostExecute(String result) {
450
448
 
451
- Log.d("ClientActivity.ResultReceiver.onPostExecute", "判定="+result);
449
+ Log.d("ResultReceiver.onPostExecute", "判定="+result);
452
450
 
453
451
  if(result == null) return;
454
452
 
455
- Log.d("ClientActivity.ResultReceiver.onPostExecute", "判定表示");
453
+ Log.d("ResultReceiver.onPostExecute", "判定表示");
456
454
 
457
455
  resultView.setText(result);
458
456
 
459
457
  if(result.equalsIgnoreCase("OK")) {
460
458
 
461
- Log.d("ClientActivity.ResultReceiver.onPostExecute", "次問題");
459
+ Log.d("ResultReceiver.onPostExecute", "次問題");
462
460
 
463
461
  new QuestionReceiver().execute();
464
462
 
465
463
  } else {
466
464
 
467
- Log.d("ClientActivity.ResultReceiver.onPostExecute", "再回答");
465
+ Log.d("ResultReceiver.onPostExecute", "再回答");
468
466
 
469
467
  answerView.setText("");
470
468
 

4

クライアントコード修正

2019/01/31 08:46

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -1,4 +1,4 @@
1
- 普通にクライアント-サーバ型の通信ではどういう感じになるかということで書いてみました.
1
+ 普通にクライアント-サーバではどういう感じになるかということで書いてみました.
2
2
 
3
3
  すいません, 動くものにしようと書いていますが, 一気に書いた状態でまだ動かしていません.
4
4
 
@@ -8,45 +8,13 @@
8
8
 
9
9
  なるべく説明を入れてみましたが... あくまで参考ということでお願いします.
10
10
 
11
-
12
-
13
11
  流れを図にしてみました.
14
12
 
15
13
  ![イメージフロー](a8d65def9178e91c9e95b2881904730b.gif)
16
14
 
17
15
 
18
16
 
19
- サーバ側です
20
-
21
- ```java(android)
17
+ ```java
22
-
23
- package com.example.transqa;
24
-
25
-
26
-
27
- import android.os.AsyncTask;
28
-
29
- import android.support.v7.app.AppCompatActivity;
30
-
31
- import android.os.Bundle;
32
-
33
-
34
-
35
- import java.io.BufferedReader;
36
-
37
- import java.io.BufferedWriter;
38
-
39
- import java.io.IOException;
40
-
41
- import java.io.InputStreamReader;
42
-
43
- import java.io.OutputStreamWriter;
44
-
45
- import java.net.ServerSocket;
46
-
47
- import java.net.Socket;
48
-
49
-
50
18
 
51
19
  public class ServerActivity extends AppCompatActivity {
52
20
 
@@ -88,11 +56,11 @@
88
56
 
89
57
  try {
90
58
 
91
- while(true) { //延々と受付待ち
59
+ while(true) {//延々と受付待ち
92
-
60
+
93
- Socket s = ss.accept(); //サーバは受付だけ
61
+ Socket s = ss.accept();//サーバは受付だけ
94
-
62
+
95
- new Questioner().execute(s); //受付したら, 後は専用スレッドに任せます.
63
+ new Questioner().execute(s);//受付したら, 後は専用スレッドに任せます.
96
64
 
97
65
  }
98
66
 
@@ -118,7 +86,7 @@
118
86
 
119
87
  protected String doInBackground(Object... objects) {
120
88
 
121
- Socket s = (Socket)objects[0]; //パラメータ1つめは Socket.
89
+ Socket s = (Socket)objects[0];//パラメータ1つめは Socket.
122
90
 
123
91
  try {
124
92
 
@@ -244,229 +212,269 @@
244
212
 
245
213
  ```
246
214
 
247
- クライアント側です
248
-
249
- ```java(android)
215
+ ```java
250
-
251
- package com.example.transqa;
252
-
253
-
254
-
255
- import android.os.AsyncTask;
256
-
257
- import android.os.Bundle;
258
-
259
- import android.support.v7.app.AppCompatActivity;
260
-
261
- import android.view.View;
262
-
263
- import android.widget.Button;
264
-
265
- import android.widget.EditText;
266
-
267
- import android.widget.TextView;
268
-
269
-
270
-
271
- import java.io.BufferedReader;
272
-
273
- import java.io.BufferedWriter;
274
-
275
- import java.io.IOException;
276
-
277
- import java.io.InputStreamReader;
278
-
279
- import java.io.OutputStreamWriter;
280
-
281
- import java.net.Socket;
282
-
283
-
284
216
 
285
217
  public class ClientActivity extends AppCompatActivity {
286
218
 
219
+ private TextView questionView;
220
+
221
+ private EditText answerView;
222
+
223
+ private TextView resultView;
224
+
225
+ private Button finalAnswer;
226
+
227
+ @Override
228
+
229
+ protected void onCreate(Bundle savedInstanceState) {
230
+
231
+ super.onCreate(savedInstanceState);
232
+
233
+ setContentView(R.layout.activity_client);
234
+
235
+ questionView = (TextView)findViewById(R.id.question);
236
+
237
+ answerView = (EditText)findViewById(R.id.answer);
238
+
239
+ resultView = (TextView)findViewById(R.id.result);
240
+
241
+ //回答欄に入力したらボタンを押し, サーバに送信
242
+
243
+ finalAnswer = (Button)findViewById(R.id.finalAnswer);
244
+
245
+ finalAnswer.setOnClickListener(new View.OnClickListener() {
246
+
247
+ @Override
248
+
249
+ public void onClick(View v) {
250
+
251
+ String answer = answerView.getText().toString();
252
+
253
+ if(answer.length() == 0) return;//入ってなかったら無視
254
+
255
+ new ResultReceiver().execute(answer);
256
+
257
+ }
258
+
259
+ });
260
+
261
+ manager = new ConnectionManager("10.0.2.2", 8181);//これはエミュレータでの設定(telnet localhost 5554 > redir add tcp:8080:8181 後)
262
+
263
+ new QuestionReceiver().execute();//最初の問題を受信, 表示して回答を待ちます.
264
+
265
+ }
266
+
267
+ private ConnectionManager manager;
268
+
269
+ private class ConnectionManager {
270
+
271
+ private String host;
272
+
273
+ private int port;
274
+
287
275
  private Socket s;
288
276
 
289
277
  private BufferedWriter w;
290
278
 
291
279
  private BufferedReader r;
292
280
 
293
-
281
+ ConnectionManager(String host, int port) {
282
+
294
-
283
+ this.host = host;
284
+
285
+ this.port = port;
286
+
287
+ }
288
+
289
+ void connect() throws IOException {
290
+
291
+ if(s == null) {
292
+
293
+ Log.d("ClientActivity.ConnectionManager.connect", "接続");
294
+
295
+ s = new Socket(host, port);
296
+
297
+ try {
298
+
299
+ w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
300
+
301
+ r = new BufferedReader(new InputStreamReader(s.getInputStream()));
302
+
303
+ Log.d("ClientActivity.ConnectionManager.connect", "接続成功");
304
+
295
- private TextView questionView;
305
+ } catch(IOException e) {
306
+
296
-
307
+ Log.e("ClientActivity.ConnectionManager.connect", "接続失敗", e);
308
+
297
- private EditText answerView;
309
+ try { s.close(); } catch(IOException ignore) {}
298
-
310
+
299
- private TextView resultView;
311
+ s = null; w = null; r = null;
312
+
300
-
313
+ throw e;
314
+
315
+ }
316
+
317
+ }
318
+
319
+ }
320
+
321
+ BufferedReader getReader() throws IOException { connect(); return r; }
322
+
323
+ BufferedWriter getWriter() throws IOException { connect(); return w; }
324
+
325
+ void disconnect() { if(s == null) try { s.close(); } catch(IOException ignore) {} }
326
+
327
+ }
328
+
301
- private Button finalAnswer;
329
+ private class QuestionReceiver extends AsyncTask<Void,Void,String> {
302
-
303
-
304
330
 
305
331
  @Override
306
332
 
333
+ protected String doInBackground(Void... aVoid) {
334
+
335
+ try {
336
+
337
+ Log.d("ClientActivity.QuestionReceiver.doInBackground", "問題受信");
338
+
339
+ BufferedReader r = manager.getReader();
340
+
341
+ int linecount = Integer.parseInt(r.readLine());
342
+
343
+ Log.d("ClientActivity.QuestionReceiver.doInBackground", "linecount="+linecount);
344
+
345
+ if(linecount == 0) return null;
346
+
347
+ String text = "";
348
+
349
+ for(int i=0; i<linecount; i++) text += r.readLine() + "\n";
350
+
351
+ Log.d("ClientActivity.QuestionReceiver.doInBackground", "text="+text);
352
+
353
+ return text;
354
+
355
+ } catch (IOException e) {
356
+
357
+ Log.e("ClientActivity.QuestionReceiver.doInBackground", "問題受信異常", e);
358
+
359
+ e.printStackTrace();
360
+
361
+ }
362
+
363
+ return null;
364
+
365
+ }
366
+
367
+ @Override
368
+
307
- protected void onCreate(Bundle savedInstanceState) {
369
+ protected void onPostExecute(String text) {
308
-
309
- super.onCreate(savedInstanceState);
370
+
310
-
311
- setContentView(R.layout.activity_server);
312
-
313
-
314
-
315
- questionView = (TextView)findViewById(R.id.question);
371
+ Log.d("ClientActivity.QuestionReceiver.onPostExecute", "text="+text);
316
-
317
- answerView = (EditText)findViewById(R.id.answer);
372
+
318
-
319
- resultView = (TextView)findViewById(R.id.result);
373
+ if(text == null) {
320
-
321
-
322
-
323
- //回答欄に入力したらボタンを押し, サーバに送信
374
+
324
-
325
- finalAnswer = (Button)findViewById(R.id.finalAnswer);
375
+ finalAnswer.setText("終わります");
326
376
 
327
377
  finalAnswer.setOnClickListener(new View.OnClickListener() {
328
378
 
329
- @Override
379
+ @Override
330
-
380
+
331
- public void onClick(View v) {
381
+ public void onClick(View v) {
332
-
333
- String answer = answerView.getText().toString();
382
+
334
-
335
- if(answer.length() == 0) return; //入ってなかったら無視
336
-
337
- try {
338
-
339
- w.write(answer + "\n"); //サーバに送信
340
-
341
- w.flush();
342
-
343
- new ResultReceiver().execute(); //結果を別タスクで受ける
383
+ Log.d("ClientActivity.QuestionReceiver.onPostExecute", "finalAnswer.OnClick");
344
-
345
- //ここでメインも結果を受け取るまで止まりたい所ですが, メインスレッドを止めてはいけません.
384
+
346
-
347
- //ResultReceiver側でぐるぐる回るプログレスを出しておくのが良いでしょう.
348
-
349
- } catch (IOException e) {
350
-
351
- e.printStackTrace();
385
+ manager.disconnect();
386
+
352
-
387
+ ClientActivity.this.finish();
388
+
353
- }
389
+ }
354
-
355
- }
356
390
 
357
391
  });
358
392
 
359
- try {
360
-
361
- s = new Socket("192.168.1.1", 8080);
362
-
363
- w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
364
-
365
- r = new BufferedReader(new InputStreamReader(s.getInputStream()));
366
-
367
- setQuestions(); //問題を Socket(実際は BufferedReader) で受け取って表示. 回答待ち
368
-
369
- } catch (IOException e) {
370
-
371
- e.printStackTrace();
372
-
373
- }
374
-
375
- }
376
-
377
- //falseを返したら問題が無くなり終了です. trueを返したら(次の)問題が表示されたことになります.
378
-
379
- private boolean setQuestions() throws IOException {
380
-
381
- //問題文が送られてくるので受け取ります
382
-
383
- int linecount = Integer.parseInt(r.readLine()); //まず問題文の行数
384
-
385
- if(linecount == 0) return false; //もし行数が 0 だったら問題が無くなったので終了ということにしました.
386
-
387
- String text = "";
388
-
389
- for(int i=0; i<linecount; i++) text += r.readLine() + "\n"; //問題文を1行ずつ受け取って改行を付けて繋げます.
390
-
391
- questionView.setText(text); //問題を表示し
392
-
393
- answerView.setText(""); //各欄をクリアして
394
-
395
- resultView.setText("");
396
-
397
- answerView.requestFocus(); //回答欄にフォーカスして待ちます.
398
-
399
- return true;
400
-
401
- }
402
-
403
- private class ResultReceiver extends AsyncTask<Object,Object,String> {
404
-
405
- @Override
406
-
407
- protected String doInBackground(Object... object) {
408
-
409
- try {
410
-
411
- return r.readLine();
412
-
413
- } catch(IOException e) {
414
-
415
- e.printStackTrace();
416
-
417
- }
418
-
419
- return null;
420
-
421
- }
422
-
423
- @Override
424
-
425
- protected void onPostExecute(String s) {
426
-
427
- if(s == null) return; //通信が切れるとこの条件が一致してしまいます. その場合どうしましょう.
428
-
429
- resultView.setText(s);
430
-
431
- if(s.equalsIgnoreCase("OK")) { //正解だったら
432
-
433
- try {
434
-
435
- if(!setQuestions()) { //次の問題を受信・表示します. が, 問題が無くなったら終わります
436
-
437
- finalAnswer.setText("終わります");
438
-
439
- finalAnswer.setOnClickListener(new View.OnClickListener() {
440
-
441
- @Override
442
-
443
- public void onClick(View v) {
444
-
445
- ClientActivity.this.finish(); //かなり強引です!
446
-
447
- }
448
-
449
- });
450
-
451
- }
452
-
453
- } catch (IOException e) {
454
-
455
- e.printStackTrace();
456
-
457
- }
458
-
459
- } else { //不正解だったら
460
-
461
- answerView.setText(""); //回答欄をクリアして
462
-
463
- answerView.requestFocus(); //もう一度回答欄にフォーカスして待ちます.
464
-
465
- }
466
-
467
- }
468
-
469
- }
393
+ return;
394
+
395
+ }
396
+
397
+ Log.d("ClientActivity.QuestionReceiver.onPostExecute", "問題表示");
398
+
399
+ questionView.setText(text);
400
+
401
+ answerView.setText("");
402
+
403
+ resultView.setText("");
404
+
405
+ answerView.requestFocus();
406
+
407
+ }
408
+
409
+ }
410
+
411
+ private class ResultReceiver extends AsyncTask<String,Object,String> {
412
+
413
+ @Override
414
+
415
+ protected String doInBackground(String... answers) {
416
+
417
+ String answer = answers[0];
418
+
419
+ try {
420
+
421
+ Log.d("ClientActivity.ResultReceiver.doInBackground", "回答送信 answer="+answer);
422
+
423
+ BufferedWriter w = manager.getWriter();
424
+
425
+ w.write(answer + "\n");
426
+
427
+ w.flush();
428
+
429
+ Log.d("ClientActivity.ResultReceiver.doInBackground", "判定受信");
430
+
431
+ BufferedReader r = manager.getReader();
432
+
433
+ return r.readLine();
434
+
435
+ } catch(IOException e) {
436
+
437
+ Log.e("ClientActivity.ResultReceiver.doInBackground", "異常", e);
438
+
439
+ e.printStackTrace();
440
+
441
+ }
442
+
443
+ return null;
444
+
445
+ }
446
+
447
+ @Override
448
+
449
+ protected void onPostExecute(String result) {
450
+
451
+ Log.d("ClientActivity.ResultReceiver.onPostExecute", "判定="+result);
452
+
453
+ if(result == null) return;
454
+
455
+ Log.d("ClientActivity.ResultReceiver.onPostExecute", "判定表示");
456
+
457
+ resultView.setText(result);
458
+
459
+ if(result.equalsIgnoreCase("OK")) {
460
+
461
+ Log.d("ClientActivity.ResultReceiver.onPostExecute", "次問題");
462
+
463
+ new QuestionReceiver().execute();
464
+
465
+ } else {
466
+
467
+ Log.d("ClientActivity.ResultReceiver.onPostExecute", "再回答");
468
+
469
+ answerView.setText("");
470
+
471
+ answerView.requestFocus();
472
+
473
+ }
474
+
475
+ }
476
+
477
+ }
470
478
 
471
479
  }
472
480
 

3

スレッド開始メソッド間違い

2019/01/31 03:42

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -60,7 +60,7 @@
60
60
 
61
61
  try {
62
62
 
63
- new Thread(new Server(8080)).run();
63
+ new Thread(new Server(8080)).start();
64
64
 
65
65
  } catch (IOException e) {
66
66
 

2

イメージフロー図追加

2019/01/30 14:54

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
 
12
12
 
13
+ 流れを図にしてみました.
14
+
15
+ ![イメージフロー](a8d65def9178e91c9e95b2881904730b.gif)
16
+
17
+
18
+
13
19
  サーバ側です
14
20
 
15
21
  ```java(android)

1

誤字

2019/01/30 11:17

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  すいません, 動くものにしようと書いていますが, 一気に書いた状態でまだ動かしていません.
4
4
 
5
- レイアウトはクライアント側で, 問題表示TextView id=question, 回答欄EditView id=answer, 判定表示TextView id=result, 回答送信Button id=finalAnswer です. ボタンは全問題終了時のクライアント終了も兼ねています.
5
+ レイアウトはクライアント側で, 問題表示TextView id=question, 回答欄EditText id=answer, 判定表示TextView id=result, 回答送信Button id=finalAnswer です. ボタンは全問題終了時のクライアント終了も兼ねています.
6
6
 
7
7
  サーバ側は使っていません.
8
8