回答編集履歴

2

大幅な改善

2019/07/09 20:21

投稿

reishisu
reishisu

スコア39

test CHANGED
@@ -16,6 +16,440 @@
16
16
 
17
17
  (今回は通信だけの質問だったので、別スレッドで実行しているので受け取ったメッセージをメインスレッドにデータの送信ができていないので完全に完成はしておりません。)
18
18
 
19
+
20
+
21
+ [C#のコード](https://gist.github.com/reishisu/c426018f02f9159ae200dbfc651b08ab)
22
+
23
+ 回答して頂いたjimbe様、解決のヒントを下さり本当にありがとうございました。
24
+
25
+
26
+
27
+ ### 追記
28
+
29
+ 一応、目的のとりあえず動くコードは(多分)作れたので追記させて頂きます。
30
+
31
+ [Javaのコード](https://gist.github.com/reishisu/7f2b568d0f598477a651b42647c4c527)
32
+
33
+ [C#のコード](https://gist.github.com/reishisu/3f73502ab2319129139939f2585cae37)
34
+
35
+
36
+
37
+ ### 追記(2019年7月10日)
38
+
39
+ Javaのコードを2つに分けることでうまく、排他制御することに成功しました!!
40
+
41
+ サーバー側でアクセスされる度にクライアントのIPアドレスを確認し、クライアントのIPアドレスを管理しているリストにあればそのままThreadを非同期で実行させており、なければリストに追加して同じくThreadを非同期で実行させております。
42
+
43
+ Threadの中では、メインスレッドにあるbroadcast関数をsynchronized修飾子をつけ排他制御しながら実行しているのでうまくスレッドの生成順に実行させることができ、上手くできたかなぁと思っております。
44
+
45
+ また、アプリを落とした時の切断エラーに関してもエラーをcatchした瞬間に当該IPをリストから削除することで他のスレッドに干渉せずに出来ました!
46
+
47
+ ```Java
48
+
49
+ package raspi_server;
50
+
51
+
52
+
53
+ import java.io.DataOutputStream;
54
+
55
+ import java.io.IOException;
56
+
57
+ import java.net.ServerSocket;
58
+
59
+ import java.net.Socket;
60
+
61
+ import java.util.ArrayList;
62
+
63
+
64
+
65
+ /**
66
+
67
+ * ラズパイ上で動かすチャットのサーバークラスです
68
+
69
+ * @author reishisu
70
+
71
+ */
72
+
73
+ public class ChatServer {
74
+
75
+
76
+
77
+ /**
78
+
79
+ * ソケット通信を行うポート
80
+
81
+ */
82
+
83
+ private static final int PORT = 25252;
84
+
85
+ /**
86
+
87
+ * チャットサーバーの窓口
88
+
89
+ */
90
+
91
+ private static ServerSocket server_socket;
92
+
93
+
94
+
95
+
96
+
97
+ /**
98
+
99
+ * 接続してきたIPアドレス
100
+
101
+ */
102
+
103
+ private static ArrayList<Socket> socket_list = new ArrayList<>();
104
+
105
+ /**
106
+
107
+ * チャットのナンバー
108
+
109
+ */
110
+
111
+ private static int chat_number = 1;
112
+
113
+
114
+
115
+ /**
116
+
117
+ * メイン関数
118
+
119
+ * @param args コマンドライン引数
120
+
121
+ */
122
+
123
+ public static void main(String[] args) {
124
+
125
+ try {
126
+
127
+ // 既にサーバーが建っていない時サーバーソケットの生成
128
+
129
+ if (server_socket == null) {
130
+
131
+ server_socket = new ServerSocket(PORT);
132
+
133
+ System.out.println("サーバー稼働中...");
134
+
135
+ }
136
+
137
+ // サーバー稼働
138
+
139
+ while (true) {
140
+
141
+ // クライアントからの接続が来るまで待機
142
+
143
+ Socket client_socket = server_socket.accept();
144
+
145
+ // 新規か確認
146
+
147
+ boolean is_new = true;
148
+
149
+ // 新規のIPがないかを走査する
150
+
151
+ for(Socket client : socket_list) {
152
+
153
+ if ( client.getInetAddress().toString().equals(client_socket.getInetAddress().toString())) {
154
+
155
+ System.out.println("同じとこからきてる!");
156
+
157
+ new ClientReciever(client_socket).start();
158
+
159
+ is_new = false;
160
+
161
+ }
162
+
163
+ }
164
+
165
+ // 新規の場合
166
+
167
+ if (is_new) {
168
+
169
+ // ソケットリストに追加
170
+
171
+ socket_list.add(client_socket);
172
+
173
+ // 新規ソケット用のスレッドを実行
174
+
175
+ new ClientReciever(client_socket).start();
176
+
177
+ System.out.println("新規さん入ります!\nIPアドレス:" + client_socket.getInetAddress().toString() + "\n合計接続数:" + socket_list.size());
178
+
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ catch (Exception e) {
186
+
187
+ System.err.println("エラー発生!!");
188
+
189
+ e.printStackTrace();
190
+
191
+ }
192
+
193
+ }
194
+
195
+
196
+
197
+ /**
198
+
199
+ * クライアントにメッセージをブロードキャストするための関数
200
+
201
+ * @param message 送信文字列
202
+
203
+ */
204
+
205
+ public static synchronized void broadcast(String message) {
206
+
207
+ byte[] buffer = new byte[4096];
208
+
209
+ DataOutputStream dataOutputStream = null;
210
+
211
+ try {
212
+
213
+ buffer = message.getBytes("UTF-8");
214
+
215
+
216
+
217
+ for (Socket client : socket_list) {
218
+
219
+ try {
220
+
221
+ dataOutputStream = new DataOutputStream(new Socket(client.getInetAddress().toString().split("/")[1], PORT).getOutputStream());
222
+
223
+ dataOutputStream.write(buffer);
224
+
225
+ dataOutputStream.flush();
226
+
227
+ } catch (Exception e) {
228
+
229
+ System.out.println(client.getInetAddress().toString().split("/")[1] + "との接続が切れました");
230
+
231
+ socket_list.remove(client);
232
+
233
+ }
234
+
235
+ }
236
+
237
+ } catch (IOException e) { e.printStackTrace(); }
238
+
239
+ }
240
+
241
+
242
+
243
+ /**
244
+
245
+ * チャットナンバーを返す
246
+
247
+ * @return 現在のチャットナンバー
248
+
249
+ */
250
+
251
+ public static synchronized int getChat_number() {
252
+
253
+ chat_number++;
254
+
255
+ return chat_number-1;
256
+
257
+ }
258
+
259
+ }
260
+
261
+
262
+
263
+ ```
264
+
265
+ ```Java
266
+
267
+ package raspi_server;
268
+
269
+
270
+
271
+ import java.io.DataInputStream;
272
+
273
+ import java.net.Socket;
274
+
275
+ import java.text.SimpleDateFormat;
276
+
277
+ import java.util.Date;
278
+
279
+
280
+
281
+ /**
282
+
283
+ * チャットのアプリケーションクラスです
284
+
285
+ * @author reishisu
286
+
287
+ */
288
+
289
+ public class ClientReciever extends Thread {
290
+
291
+
292
+
293
+ /**
294
+
295
+ * 受信する対象のクライアント
296
+
297
+ */
298
+
299
+ private Socket client;
300
+
301
+ /**
302
+
303
+ * クライアントのデータ受信窓口
304
+
305
+ */
306
+
307
+ private DataInputStream data_input_stream;
308
+
309
+ /**
310
+
311
+ * 無限ループなのでフラグを使って意図的にスレッドを終了させる
312
+
313
+ */
314
+
315
+ public boolean do_thread_finish;
316
+
317
+ /**
318
+
319
+ * // タイムスタンプのテンプレート
320
+
321
+ */
322
+
323
+ SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
324
+
325
+
326
+
327
+
328
+
329
+ /**
330
+
331
+ * コンストラクタ
332
+
333
+ * @param client 受信の対応をするクライアント用の窓口
334
+
335
+ */
336
+
337
+ public ClientReciever(Socket client) {
338
+
339
+ try {
340
+
341
+ System.out.println("ClientReciever Called!!");
342
+
343
+ this.client = client;
344
+
345
+ this.data_input_stream = new DataInputStream(client.getInputStream());
346
+
347
+ }
348
+
349
+ catch (Exception e) {
350
+
351
+ System.out.println("スレッド生成時にエラーが発生しました...");
352
+
353
+ e.printStackTrace();
354
+
355
+ }
356
+
357
+ }
358
+
359
+
360
+
361
+ /**
362
+
363
+ * ひたすらデータの受信を行う
364
+
365
+ */
366
+
367
+ public void run() {
368
+
369
+ // 文字列を受け取るバッファ
370
+
371
+ byte[] buffer = new byte[4096];
372
+
373
+ // 受信文字列
374
+
375
+ String send_message = "";
376
+
377
+ // スレッド終了の合図が出るまで実行
378
+
379
+ while(!do_thread_finish) {
380
+
381
+ try {
382
+
383
+ int read_resuld = data_input_stream.read(buffer);
384
+
385
+ // データの受信が確認されなかった時は実行されない
386
+
387
+ if (read_resuld == 0 || read_resuld == -1) continue;
388
+
389
+ // 受信時間の計測を開始
390
+
391
+ long start_time = System.currentTimeMillis();
392
+
393
+ // 受信した文字列
394
+
395
+ String recieve_string = new String(buffer, "UTF-8");
396
+
397
+ // 計測終了
398
+
399
+ long end_time = System.currentTimeMillis();
400
+
401
+ // 受信した文字列に付加情報をつけて送信文字列を作成
402
+
403
+ send_message = new StringBuilder().append(ChatServer.getChat_number()).append(" IPアドレス:").append(client.getInetAddress().toString().split("/")[1])
404
+
405
+ .append(":").append(time_stamp.format(new Date())).append(" [").append((end_time - start_time))
406
+
407
+ .append("ms]\n").append(recieve_string).append("\n").toString();
408
+
409
+ // 送信文字列を表示
410
+
411
+ System.out.println(send_message);
412
+
413
+ // 登録リストへ送信文字列をブロードキャストする
414
+
415
+ ChatServer.broadcast(send_message);
416
+
417
+ do_thread_finish = !do_thread_finish;
418
+
419
+ }
420
+
421
+ catch (Exception e) {
422
+
423
+ e.printStackTrace();
424
+
425
+ // 受信した文字列に付加情報をつけて送信文字列を作成
426
+
427
+ send_message = new StringBuilder().append(ChatServer.getChat_number()).append(" IPアドレス:").append(client.getInetAddress().toString().split("/")[1])
428
+
429
+ .append(":").append(time_stamp.format(new Date())).append(" 9999[ms]\n受信失敗...\n").toString();
430
+
431
+ // 送信文字列を表示
432
+
433
+ System.out.println(send_message);
434
+
435
+ // 登録リストへ送信文字列をブロードキャストする
436
+
437
+ ChatServer.broadcast(send_message);
438
+
439
+ do_thread_finish = !do_thread_finish;
440
+
441
+ }
442
+
443
+ }
444
+
445
+ }
446
+
447
+ }
448
+
449
+
450
+
451
+ ```
452
+
19
453
  ```C#
20
454
 
21
455
  using System.Collections;
@@ -36,6 +470,8 @@
36
470
 
37
471
  using System.Threading.Tasks;
38
472
 
473
+ using System.Threading;
474
+
39
475
 
40
476
 
41
477
  public class ChatClient : MonoBehaviour {
@@ -52,6 +488,16 @@
52
488
 
53
489
 
54
490
 
491
+ public static string a;
492
+
493
+
494
+
495
+ //おまじない
496
+
497
+ private SynchronizationContext context;
498
+
499
+
500
+
55
501
  // サーバー情報
56
502
 
57
503
  private string server_ip_address = "192.168.0.25";
@@ -88,6 +534,12 @@
88
534
 
89
535
  void Start() {
90
536
 
537
+
538
+
539
+ context = SynchronizationContext.Current;
540
+
541
+
542
+
91
543
  //Componentを扱えるようにする
92
544
 
93
545
  input_field = input_field.GetComponent<InputField>();
@@ -102,6 +554,26 @@
102
554
 
103
555
 
104
556
 
557
+ private void Update() {
558
+
559
+ if (a != "") {
560
+
561
+ GameObject instance = Instantiate(chat_log);
562
+
563
+ instance.transform.parent = content.transform;
564
+
565
+ instance.transform.localScale = new Vector3(1, 1, 1);
566
+
567
+ instance.GetComponent<Text>().text = a;
568
+
569
+ a = "";
570
+
571
+ }
572
+
573
+ }
574
+
575
+
576
+
105
577
  public void InputText() {
106
578
 
107
579
  //テキストにinputFieldの内容を反映
@@ -136,22 +608,6 @@
136
608
 
137
609
 
138
610
 
139
- // データを受信
140
-
141
- //network_stream.Read(buffer, 0, buffer.Length);
142
-
143
- //string message = Encoding.UTF8.GetString(buffer);
144
-
145
- //GameObject instance = Instantiate(chat_log);
146
-
147
- //instance.transform.parent = content.transform;
148
-
149
- //instance.transform.localScale = new Vector3(1, 1, 1);
150
-
151
- //instance.GetComponent<Text>().text = message;
152
-
153
-
154
-
155
611
  network_stream.Close();
156
612
 
157
613
  }
@@ -162,6 +618,12 @@
162
618
 
163
619
  public void Listener() {
164
620
 
621
+
622
+
623
+ SynchronizationContext.SetSynchronizationContext(context);
624
+
625
+
626
+
165
627
  listener = new TcpListener(IPAddress.Any, port);
166
628
 
167
629
 
@@ -214,13 +676,7 @@
214
676
 
215
677
  Debug.Log(message);
216
678
 
217
- GameObject instance = Instantiate(chat_log);
218
-
219
- instance.transform.parent = content.transform;
220
-
221
- instance.transform.localScale = new Vector3(1, 1, 1);
222
-
223
- instance.GetComponent<Text>().text = message;
679
+ a = message;
224
680
 
225
681
 
226
682
 
@@ -243,523 +699,3 @@
243
699
 
244
700
 
245
701
  ```
246
-
247
-
248
-
249
- 回答して頂いたjimbe様、解決のヒントを下さり本当にありがとうございました。
250
-
251
-
252
-
253
- ### 追記
254
-
255
- 一応、目的のとりあえず動くコードは(多分)作れたので追記させて頂きます。
256
-
257
- ```Java
258
-
259
- import java.io.DataInputStream;
260
-
261
- import java.io.DataOutputStream;
262
-
263
- import java.io.IOException;
264
-
265
- import java.io.InputStream;
266
-
267
- import java.net.InetAddress;
268
-
269
- import java.net.ServerSocket;
270
-
271
- import java.net.Socket;
272
-
273
- import java.text.SimpleDateFormat;
274
-
275
- import java.util.ArrayList;
276
-
277
- import java.util.Date;
278
-
279
-
280
-
281
- /**
282
-
283
- * ラズパイ上で動かすチャットのサーバークラスです
284
-
285
- * @author reishisu
286
-
287
- */
288
-
289
- public class ChatServer {
290
-
291
-
292
-
293
- /**
294
-
295
- * ソケット通信を行うポート
296
-
297
- */
298
-
299
- public static final int PORT = 25252;
300
-
301
- /**
302
-
303
- * チャットサーバーの窓口
304
-
305
- */
306
-
307
- private static ServerSocket server_socket;
308
-
309
- /**
310
-
311
- * 接続してきたIPアドレス
312
-
313
- */
314
-
315
- private static ArrayList<InetAddress> client_list = new ArrayList<>();
316
-
317
-
318
-
319
- /**
320
-
321
- * メイン関数
322
-
323
- * @param args コマンドライン引数
324
-
325
- */
326
-
327
- public static void main(String[] args) {
328
-
329
- try {
330
-
331
- // 既にサーバーが建っていない時サーバーソケットの生成
332
-
333
- if (server_socket == null) {
334
-
335
- server_socket = new ServerSocket(PORT);
336
-
337
- System.out.println("サーバー稼働中...");
338
-
339
- }
340
-
341
-
342
-
343
- // 受信カウンタ
344
-
345
- int count = 1;
346
-
347
-
348
-
349
- // サーバー稼働
350
-
351
- while (true) {
352
-
353
- // クライアントからの接続が来るまで待機
354
-
355
- Socket client_socket = server_socket.accept();
356
-
357
-
358
-
359
- // 新規か確認
360
-
361
- boolean is_new = true;
362
-
363
- for(InetAddress ip : client_list) {
364
-
365
- if (ip.toString().equals(client_socket.getInetAddress().toString())) {
366
-
367
- is_new = false;
368
-
369
- } else {
370
-
371
- System.out.println("違う?" + ip + "==" + client_socket.getInetAddress());
372
-
373
- }
374
-
375
- }
376
-
377
- if (is_new) {
378
-
379
- client_list.add(client_socket.getInetAddress());
380
-
381
- System.out.println("追加された:" + client_socket.getInetAddress().toString() + ":" + client_list.size());
382
-
383
- }
384
-
385
-
386
-
387
- // 計測開始
388
-
389
- long start_time = System.currentTimeMillis();
390
-
391
-
392
-
393
- // クライアントから文字列をバイト列で受信
394
-
395
- InputStream input_stream = client_socket.getInputStream();
396
-
397
- DataInputStream data_input_stream = new DataInputStream(input_stream);
398
-
399
-
400
-
401
- // 文字列を受け取るバッファー
402
-
403
- byte[] buffer = new byte[4096];
404
-
405
- int byte_count = 0;
406
-
407
- String message = "";
408
-
409
- try {
410
-
411
- byte_count = data_input_stream.read(buffer);
412
-
413
- if (byte_count == 0) return;
414
-
415
- String view_string = new String(buffer, "UTF-8");
416
-
417
- long end_time = System.currentTimeMillis();
418
-
419
- SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
420
-
421
- message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" +
422
-
423
- time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n" + view_string + "\n";
424
-
425
- System.out.println(message);
426
-
427
- count++;
428
-
429
-
430
-
431
- send(message);
432
-
433
- }
434
-
435
- catch (Exception e) {
436
-
437
- long end_time = System.currentTimeMillis();
438
-
439
- SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
440
-
441
- message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" +
442
-
443
- time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n受信失敗...\n";
444
-
445
- System.out.println(message);
446
-
447
- count++;
448
-
449
-
450
-
451
- send(message);
452
-
453
- }
454
-
455
- }
456
-
457
- }
458
-
459
- catch (Exception e) {
460
-
461
- System.err.println("エラー発生!!");
462
-
463
- e.printStackTrace();
464
-
465
- }
466
-
467
- }
468
-
469
-
470
-
471
- public static void send(String message) {
472
-
473
- byte[] buffer = new byte[4096];
474
-
475
- DataOutputStream dataOutputStream = null;
476
-
477
- try {
478
-
479
- buffer = message.getBytes("UTF-8");
480
-
481
-
482
-
483
- for (InetAddress ip : client_list) {
484
-
485
- try {
486
-
487
- dataOutputStream = new DataOutputStream(new Socket(ip.toString().split("/")[1], PORT).getOutputStream());
488
-
489
- dataOutputStream.write(buffer);
490
-
491
- dataOutputStream.flush();
492
-
493
- dataOutputStream.close();
494
-
495
- } catch (Exception e) {
496
-
497
- }
498
-
499
- }
500
-
501
-
502
-
503
- } catch (IOException e) {
504
-
505
- // TODO 自動生成された catch ブロック
506
-
507
- e.printStackTrace();
508
-
509
- }
510
-
511
- }
512
-
513
- }
514
-
515
- ```
516
-
517
- ```C#
518
-
519
- using System.Collections;
520
-
521
- using System.Collections.Generic;
522
-
523
- using System;
524
-
525
- using UnityEngine;
526
-
527
- using UnityEngine.UI;
528
-
529
- using System.Net.Sockets;
530
-
531
- using System.Text;
532
-
533
- using System.Net;
534
-
535
- using System.Threading.Tasks;
536
-
537
- using System.Threading;
538
-
539
-
540
-
541
- public class ChatClient : MonoBehaviour {
542
-
543
-
544
-
545
- // ゲームオブジェクト
546
-
547
- public InputField input_field;
548
-
549
- public GameObject content;
550
-
551
- public GameObject chat_log;
552
-
553
-
554
-
555
- public static string a;
556
-
557
-
558
-
559
- //おまじない
560
-
561
- private SynchronizationContext context;
562
-
563
-
564
-
565
- // サーバー情報
566
-
567
- private string server_ip_address = "192.168.0.25";
568
-
569
- private int port = 25252;
570
-
571
-
572
-
573
- // クライアントの送信窓口
574
-
575
- NetworkStream network_stream;
576
-
577
-
578
-
579
- // 送信内容
580
-
581
- private string send_text;
582
-
583
-
584
-
585
- // 受信用
586
-
587
- private TcpListener listener;
588
-
589
- private float request_span = 10f;
590
-
591
- private byte[] buffer = new byte[4096];
592
-
593
-
594
-
595
-
596
-
597
- // Start is called before the first frame update
598
-
599
- void Start() {
600
-
601
-
602
-
603
- context = SynchronizationContext.Current;
604
-
605
-
606
-
607
- //Componentを扱えるようにする
608
-
609
- input_field = input_field.GetComponent<InputField>();
610
-
611
-
612
-
613
- // 監視
614
-
615
- Task.Run(Listener);
616
-
617
- }
618
-
619
-
620
-
621
- private void Update() {
622
-
623
- if (a != "") {
624
-
625
- GameObject instance = Instantiate(chat_log);
626
-
627
- instance.transform.parent = content.transform;
628
-
629
- instance.transform.localScale = new Vector3(1, 1, 1);
630
-
631
- instance.GetComponent<Text>().text = a;
632
-
633
- a = "";
634
-
635
- }
636
-
637
- }
638
-
639
-
640
-
641
- public void InputText() {
642
-
643
- //テキストにinputFieldの内容を反映
644
-
645
- send_text = input_field.text;
646
-
647
- }
648
-
649
-
650
-
651
- // ボタンクリック時
652
-
653
- public void NetworkRequest() {
654
-
655
- // 接続要求
656
-
657
- network_stream = new TcpClient(server_ip_address, port).GetStream();
658
-
659
-
660
-
661
- // 送信の内容をセット
662
-
663
- if (send_text.Length == 0) return;
664
-
665
- byte[] send_string = Encoding.UTF8.GetBytes(send_text);
666
-
667
-
668
-
669
- // データを送信
670
-
671
- network_stream.Write(send_string, 0, send_string.Length);
672
-
673
-
674
-
675
- network_stream.Close();
676
-
677
- }
678
-
679
-
680
-
681
-
682
-
683
- public void Listener() {
684
-
685
-
686
-
687
- SynchronizationContext.SetSynchronizationContext(context);
688
-
689
-
690
-
691
- listener = new TcpListener(IPAddress.Any, port);
692
-
693
-
694
-
695
- Debug.Log("監視開始1");
696
-
697
-
698
-
699
- try {
700
-
701
- listener.Start();
702
-
703
- }
704
-
705
- catch (Exception e) {
706
-
707
- Debug.Log(e.Message);
708
-
709
- Debug.Log(e.TargetSite);
710
-
711
- Debug.Log(e.StackTrace);
712
-
713
- }
714
-
715
-
716
-
717
- Debug.Log("監視開始2");
718
-
719
- while (true) {
720
-
721
- //接続要求があったら受け入れる
722
-
723
- TcpClient client = listener.AcceptTcpClient();
724
-
725
-
726
-
727
- Debug.Log("きた!");
728
-
729
-
730
-
731
- network_stream = client.GetStream();
732
-
733
-
734
-
735
- // データを受信
736
-
737
- network_stream.Read(buffer, 0, buffer.Length);
738
-
739
- string message = Encoding.UTF8.GetString(buffer);
740
-
741
- Debug.Log(message);
742
-
743
- a = message;
744
-
745
-
746
-
747
- // バッファリセット
748
-
749
- buffer = new byte[4096];
750
-
751
-
752
-
753
- network_stream.Close();
754
-
755
- }
756
-
757
- }
758
-
759
-
760
-
761
- }
762
-
763
-
764
-
765
- ```

1

修正したので追記を

2019/07/09 20:21

投稿

reishisu
reishisu

スコア39

test CHANGED
@@ -247,3 +247,519 @@
247
247
 
248
248
 
249
249
  回答して頂いたjimbe様、解決のヒントを下さり本当にありがとうございました。
250
+
251
+
252
+
253
+ ### 追記
254
+
255
+ 一応、目的のとりあえず動くコードは(多分)作れたので追記させて頂きます。
256
+
257
+ ```Java
258
+
259
+ import java.io.DataInputStream;
260
+
261
+ import java.io.DataOutputStream;
262
+
263
+ import java.io.IOException;
264
+
265
+ import java.io.InputStream;
266
+
267
+ import java.net.InetAddress;
268
+
269
+ import java.net.ServerSocket;
270
+
271
+ import java.net.Socket;
272
+
273
+ import java.text.SimpleDateFormat;
274
+
275
+ import java.util.ArrayList;
276
+
277
+ import java.util.Date;
278
+
279
+
280
+
281
+ /**
282
+
283
+ * ラズパイ上で動かすチャットのサーバークラスです
284
+
285
+ * @author reishisu
286
+
287
+ */
288
+
289
+ public class ChatServer {
290
+
291
+
292
+
293
+ /**
294
+
295
+ * ソケット通信を行うポート
296
+
297
+ */
298
+
299
+ public static final int PORT = 25252;
300
+
301
+ /**
302
+
303
+ * チャットサーバーの窓口
304
+
305
+ */
306
+
307
+ private static ServerSocket server_socket;
308
+
309
+ /**
310
+
311
+ * 接続してきたIPアドレス
312
+
313
+ */
314
+
315
+ private static ArrayList<InetAddress> client_list = new ArrayList<>();
316
+
317
+
318
+
319
+ /**
320
+
321
+ * メイン関数
322
+
323
+ * @param args コマンドライン引数
324
+
325
+ */
326
+
327
+ public static void main(String[] args) {
328
+
329
+ try {
330
+
331
+ // 既にサーバーが建っていない時サーバーソケットの生成
332
+
333
+ if (server_socket == null) {
334
+
335
+ server_socket = new ServerSocket(PORT);
336
+
337
+ System.out.println("サーバー稼働中...");
338
+
339
+ }
340
+
341
+
342
+
343
+ // 受信カウンタ
344
+
345
+ int count = 1;
346
+
347
+
348
+
349
+ // サーバー稼働
350
+
351
+ while (true) {
352
+
353
+ // クライアントからの接続が来るまで待機
354
+
355
+ Socket client_socket = server_socket.accept();
356
+
357
+
358
+
359
+ // 新規か確認
360
+
361
+ boolean is_new = true;
362
+
363
+ for(InetAddress ip : client_list) {
364
+
365
+ if (ip.toString().equals(client_socket.getInetAddress().toString())) {
366
+
367
+ is_new = false;
368
+
369
+ } else {
370
+
371
+ System.out.println("違う?" + ip + "==" + client_socket.getInetAddress());
372
+
373
+ }
374
+
375
+ }
376
+
377
+ if (is_new) {
378
+
379
+ client_list.add(client_socket.getInetAddress());
380
+
381
+ System.out.println("追加された:" + client_socket.getInetAddress().toString() + ":" + client_list.size());
382
+
383
+ }
384
+
385
+
386
+
387
+ // 計測開始
388
+
389
+ long start_time = System.currentTimeMillis();
390
+
391
+
392
+
393
+ // クライアントから文字列をバイト列で受信
394
+
395
+ InputStream input_stream = client_socket.getInputStream();
396
+
397
+ DataInputStream data_input_stream = new DataInputStream(input_stream);
398
+
399
+
400
+
401
+ // 文字列を受け取るバッファー
402
+
403
+ byte[] buffer = new byte[4096];
404
+
405
+ int byte_count = 0;
406
+
407
+ String message = "";
408
+
409
+ try {
410
+
411
+ byte_count = data_input_stream.read(buffer);
412
+
413
+ if (byte_count == 0) return;
414
+
415
+ String view_string = new String(buffer, "UTF-8");
416
+
417
+ long end_time = System.currentTimeMillis();
418
+
419
+ SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
420
+
421
+ message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" +
422
+
423
+ time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n" + view_string + "\n";
424
+
425
+ System.out.println(message);
426
+
427
+ count++;
428
+
429
+
430
+
431
+ send(message);
432
+
433
+ }
434
+
435
+ catch (Exception e) {
436
+
437
+ long end_time = System.currentTimeMillis();
438
+
439
+ SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒");
440
+
441
+ message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" +
442
+
443
+ time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n受信失敗...\n";
444
+
445
+ System.out.println(message);
446
+
447
+ count++;
448
+
449
+
450
+
451
+ send(message);
452
+
453
+ }
454
+
455
+ }
456
+
457
+ }
458
+
459
+ catch (Exception e) {
460
+
461
+ System.err.println("エラー発生!!");
462
+
463
+ e.printStackTrace();
464
+
465
+ }
466
+
467
+ }
468
+
469
+
470
+
471
+ public static void send(String message) {
472
+
473
+ byte[] buffer = new byte[4096];
474
+
475
+ DataOutputStream dataOutputStream = null;
476
+
477
+ try {
478
+
479
+ buffer = message.getBytes("UTF-8");
480
+
481
+
482
+
483
+ for (InetAddress ip : client_list) {
484
+
485
+ try {
486
+
487
+ dataOutputStream = new DataOutputStream(new Socket(ip.toString().split("/")[1], PORT).getOutputStream());
488
+
489
+ dataOutputStream.write(buffer);
490
+
491
+ dataOutputStream.flush();
492
+
493
+ dataOutputStream.close();
494
+
495
+ } catch (Exception e) {
496
+
497
+ }
498
+
499
+ }
500
+
501
+
502
+
503
+ } catch (IOException e) {
504
+
505
+ // TODO 自動生成された catch ブロック
506
+
507
+ e.printStackTrace();
508
+
509
+ }
510
+
511
+ }
512
+
513
+ }
514
+
515
+ ```
516
+
517
+ ```C#
518
+
519
+ using System.Collections;
520
+
521
+ using System.Collections.Generic;
522
+
523
+ using System;
524
+
525
+ using UnityEngine;
526
+
527
+ using UnityEngine.UI;
528
+
529
+ using System.Net.Sockets;
530
+
531
+ using System.Text;
532
+
533
+ using System.Net;
534
+
535
+ using System.Threading.Tasks;
536
+
537
+ using System.Threading;
538
+
539
+
540
+
541
+ public class ChatClient : MonoBehaviour {
542
+
543
+
544
+
545
+ // ゲームオブジェクト
546
+
547
+ public InputField input_field;
548
+
549
+ public GameObject content;
550
+
551
+ public GameObject chat_log;
552
+
553
+
554
+
555
+ public static string a;
556
+
557
+
558
+
559
+ //おまじない
560
+
561
+ private SynchronizationContext context;
562
+
563
+
564
+
565
+ // サーバー情報
566
+
567
+ private string server_ip_address = "192.168.0.25";
568
+
569
+ private int port = 25252;
570
+
571
+
572
+
573
+ // クライアントの送信窓口
574
+
575
+ NetworkStream network_stream;
576
+
577
+
578
+
579
+ // 送信内容
580
+
581
+ private string send_text;
582
+
583
+
584
+
585
+ // 受信用
586
+
587
+ private TcpListener listener;
588
+
589
+ private float request_span = 10f;
590
+
591
+ private byte[] buffer = new byte[4096];
592
+
593
+
594
+
595
+
596
+
597
+ // Start is called before the first frame update
598
+
599
+ void Start() {
600
+
601
+
602
+
603
+ context = SynchronizationContext.Current;
604
+
605
+
606
+
607
+ //Componentを扱えるようにする
608
+
609
+ input_field = input_field.GetComponent<InputField>();
610
+
611
+
612
+
613
+ // 監視
614
+
615
+ Task.Run(Listener);
616
+
617
+ }
618
+
619
+
620
+
621
+ private void Update() {
622
+
623
+ if (a != "") {
624
+
625
+ GameObject instance = Instantiate(chat_log);
626
+
627
+ instance.transform.parent = content.transform;
628
+
629
+ instance.transform.localScale = new Vector3(1, 1, 1);
630
+
631
+ instance.GetComponent<Text>().text = a;
632
+
633
+ a = "";
634
+
635
+ }
636
+
637
+ }
638
+
639
+
640
+
641
+ public void InputText() {
642
+
643
+ //テキストにinputFieldの内容を反映
644
+
645
+ send_text = input_field.text;
646
+
647
+ }
648
+
649
+
650
+
651
+ // ボタンクリック時
652
+
653
+ public void NetworkRequest() {
654
+
655
+ // 接続要求
656
+
657
+ network_stream = new TcpClient(server_ip_address, port).GetStream();
658
+
659
+
660
+
661
+ // 送信の内容をセット
662
+
663
+ if (send_text.Length == 0) return;
664
+
665
+ byte[] send_string = Encoding.UTF8.GetBytes(send_text);
666
+
667
+
668
+
669
+ // データを送信
670
+
671
+ network_stream.Write(send_string, 0, send_string.Length);
672
+
673
+
674
+
675
+ network_stream.Close();
676
+
677
+ }
678
+
679
+
680
+
681
+
682
+
683
+ public void Listener() {
684
+
685
+
686
+
687
+ SynchronizationContext.SetSynchronizationContext(context);
688
+
689
+
690
+
691
+ listener = new TcpListener(IPAddress.Any, port);
692
+
693
+
694
+
695
+ Debug.Log("監視開始1");
696
+
697
+
698
+
699
+ try {
700
+
701
+ listener.Start();
702
+
703
+ }
704
+
705
+ catch (Exception e) {
706
+
707
+ Debug.Log(e.Message);
708
+
709
+ Debug.Log(e.TargetSite);
710
+
711
+ Debug.Log(e.StackTrace);
712
+
713
+ }
714
+
715
+
716
+
717
+ Debug.Log("監視開始2");
718
+
719
+ while (true) {
720
+
721
+ //接続要求があったら受け入れる
722
+
723
+ TcpClient client = listener.AcceptTcpClient();
724
+
725
+
726
+
727
+ Debug.Log("きた!");
728
+
729
+
730
+
731
+ network_stream = client.GetStream();
732
+
733
+
734
+
735
+ // データを受信
736
+
737
+ network_stream.Read(buffer, 0, buffer.Length);
738
+
739
+ string message = Encoding.UTF8.GetString(buffer);
740
+
741
+ Debug.Log(message);
742
+
743
+ a = message;
744
+
745
+
746
+
747
+ // バッファリセット
748
+
749
+ buffer = new byte[4096];
750
+
751
+
752
+
753
+ network_stream.Close();
754
+
755
+ }
756
+
757
+ }
758
+
759
+
760
+
761
+ }
762
+
763
+
764
+
765
+ ```