teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

修正

2018/11/22 02:09

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -39,7 +39,7 @@
39
39
  }
40
40
  ```
41
41
 
42
- のように、これを呼び出すMainActivityでは
42
+ のようにAsyncTaskを継承するように改めて、これを呼び出すMainActivityでは
43
43
  ```java
44
44
  public void onClick(View view) {
45
45
  SocketConnection s = new SocketConnection();

2

修正、例示追加

2018/11/22 02:09

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -21,7 +21,7 @@
21
21
  ```
22
22
  のように、繰り返し開始をaccept()の前に持ってくるべきでしょう。
23
23
 
24
- 次にクライアント側ですが、前回のご質問での私の回答に誤りがあって、Android 3.0以降ではUIスレッド上でネットワーク接続を行うとNetworkOnMainThreadExceptionという例外が飛んで正常に動作しないという問題がありました。ですから、リンクを示したサンプルは現在のAndroid SDKでは動きません。大変申し訳ありませんでした。
24
+ 次にクライアント側ですが、前回のご質問での私の回答に誤りがあって、Android 3.0以降ではUIスレッド上でネットワーク接続を行うとNetworkOnMainThreadExceptionという例外が飛んで正常に動作しないという問題がありました。ですから、リンクを示したサンプルは現在のAndroid SDKでは動きません。大変申し訳ありませんでした。
25
25
 
26
26
  正しく動くようにするには、その回答の末尾に書いた通りThreadやAsyncTaskといった別スレッド実装が必要です。記していただいたコードから修正するには、SocketConnectionクラスは
27
27
 
@@ -49,5 +49,12 @@
49
49
  のようにすれば、SocketConnectionに記述したConnect()を非同期タスクとして動かすことができるでしょう。
50
50
 
51
51
  また、Connect()の中でwhile文による永久ループを作っていますが、スレッドを永久に回す設計では正しく動作しません。このwhile文は除去して、一度のConnect()実行で一つのメッセージのやり取りのみを行う方向にしましょう。
52
+ ```java
53
+ //while (true) {
54
+ writer.println("2");
52
55
 
56
+ Log.d("test","サーバー側回答:" + reader.readLine());
57
+ //}
58
+ ```
59
+
53
60
  これだけ改修すれば、ボタンを1度押せば一つのメッセージの送受信を行えるようになるのではないかと思います。

1

回答詳細

2018/11/22 02:06

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,1 +1,53 @@
1
- コードに改めるべき点がいくらか見られますが、私が開発環境を動かせる状況にないため、細かいことを記すことができません。少し待っていただければ、検証したコードの例示付きで回答します。
1
+ コードに改めるべき点がいくらか見られますが、私が開発環境を動かせる状況にないため、細かいことを記すことができません。少し待っていただければ、検証したコードの例示付きで回答します。
2
+
3
+ ---
4
+
5
+ 遅くなりましたが、回答の詳細です。
6
+
7
+ まずサーバー側ですが、「ソケットを作成」というコメントの部分で、bind()の引数にIPアドレスを与えると接続を受け付けるネットワークを指定することになります。どこからでも受け付けるサーバーを作る場合、通常はポート番号を指定するだけです。ですから、
8
+
9
+ ```java
10
+ //ソケットを作成
11
+ sSocket = new ServerSocket();
12
+ sSocket.bind(new InetSocketAddress(ポート番号));
13
+ ```
14
+ のようにしましょう。
15
+
16
+ それから連続で待ち受けるように繰り返す区間ですが、この繰り返し方では正しく動作しないと思います。
17
+
18
+ ```java
19
+ while (true) {
20
+ socket = sSocket.accept();
21
+ ```
22
+ のように、繰り返し開始をaccept()の前に持ってくるべきでしょう。
23
+
24
+ 次にクライアント側ですが、前回のご質問での私の回答に誤りがあって、Android 3.0以降ではUIスレッド上でのネットワーク接続を行うとNetworkOnMainThreadExceptionという例外が飛んで正常に動作しないという問題がありました。ですから、リンクを示したサンプルは現在のAndroid SDKでは動きません。大変申し訳ありませんでした。
25
+
26
+ 正しく動くようにするには、その回答の末尾に書いた通りThreadやAsyncTaskといった別スレッド実装が必要です。記していただいたコードから修正するには、SocketConnectionクラスは
27
+
28
+ ```java
29
+ class SocketConnection extends AsyncTask {
30
+ @Override
31
+ protected Void doInBackground(Void... voids) {
32
+ Connect();
33
+ return null;
34
+ }
35
+
36
+ void Connect(){
37
+ // ここは現状通り
38
+ }
39
+ }
40
+ ```
41
+
42
+ のようにし、これを呼び出すMainActivityでは
43
+ ```java
44
+ public void onClick(View view) {
45
+ SocketConnection s = new SocketConnection();
46
+ s.execute();
47
+ }
48
+ ```
49
+ のようにすれば、SocketConnectionに記述したConnect()を非同期タスクとして動かすことができるでしょう。
50
+
51
+ また、Connect()の中でwhile文による永久ループを作っていますが、スレッドを永久に回す設計では正しく動作しません。このwhile文は除去して、一度のConnect()実行で一つのメッセージのやり取りのみを行う方向にしましょう。
52
+
53
+ これだけ改修すれば、ボタンを1度押せば一つのメッセージの送受信を行えるようになるのではないかと思います。