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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

1874閲覧

サーバー(Java)からUnity(C#)の複数IPへデータの送信ができない

reishisu

総合スコア39

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/07/08 18:32

編集2019/07/08 20:58

現在、ラズパイをサーバー(Java)としてローカルでUnity同士でチャットする機能を開発しようとしております。

まず、以下のコードでUnityからメッセージをラズパイへ向けて送信し、ラズパイからもUnityへ送信する事はできました。

Javaのコード
C#のコード

その後、Java側のコードをUnity側から受信があれば今まで接続があったIPアドレスに対してブロードキャストするためのsendメソッド、C#側のコードにはTcpListenerとブロードキャストされたデータを受信するためのListenerメソッドを追加し、送信してすぐ受信する処理を削除しました。

Java

1import java.io.DataInputStream; 2import java.io.DataOutputStream; 3import java.io.IOException; 4import java.io.InputStream; 5import java.net.ServerSocket; 6import java.net.Socket; 7import java.text.SimpleDateFormat; 8import java.util.ArrayList; 9import java.util.Date; 10 11/** 12 * ラズパイ上で動かすチャットのサーバークラスです 13 * @author reishisu 14 */ 15public class ChatServer { 16 17 /** 18 * ソケット通信を行うポート 19 */ 20 public static final int PORT = 25252; 21 /** 22 * チャットサーバーの窓口 23 */ 24 private static ServerSocket server_socket; 25 /** 26 * 接続してきたIPアドレス 27 */ 28 private static ArrayList<String> client_list = new ArrayList<>(); 29 30 /** 31 * メイン関数 32 * @param args コマンドライン引数 33 */ 34 public static void main(String[] args) { 35 try { 36 // 既にサーバーが建っていない時サーバーソケットの生成 37 if (server_socket == null) { 38 server_socket = new ServerSocket(PORT); 39 System.out.println("サーバー稼働中..."); 40 } 41 42 // 受信カウンタ 43 int count = 1; 44 45 // サーバー稼働 46 while (true) { 47 // クライアントからの接続が来るまで待機 48 Socket client_socket = server_socket.accept(); 49 50 // 新規か確認 51 boolean is_new = true; 52 for(String ip : client_list) { 53 if (ip == client_socket.getInetAddress().toString()) { 54 is_new = false; 55 } 56 } 57 if (is_new) client_list.add(client_socket.getInetAddress().toString()); 58 59 // 計測開始 60 long start_time = System.currentTimeMillis(); 61 62 // クライアントから文字列をバイト列で受信 63 InputStream input_stream = client_socket.getInputStream(); 64 DataInputStream data_input_stream = new DataInputStream(input_stream); 65 66 // 文字列を受け取るバッファー 67 byte[] buffer = new byte[4096]; 68 int byte_count = 0; 69 String message = ""; 70 try { 71 byte_count = data_input_stream.read(buffer); 72 if (byte_count == 0) return; 73 String view_string = new String(buffer, "UTF-8"); 74 long end_time = System.currentTimeMillis(); 75 SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒"); 76 message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" + 77 time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n" + view_string + "\n"; 78 System.out.println(message); 79 count++; 80 81 send(message, client_socket.getInetAddress().toString()); 82 } 83 catch (Exception e) { 84 long end_time = System.currentTimeMillis(); 85 SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒"); 86 message += count + " IPアドレス:" + ("" + client_socket.getInetAddress()).split("/")[1] + ":" + 87 time_stamp.format(new Date()) + " [" + (end_time - start_time) + "ms]" + "\n受信失敗...\n"; 88 System.out.println(message); 89 count++; 90 91 send(message, client_socket.getInetAddress().toString()); 92 } 93 } 94 } 95 catch (Exception e) { 96 System.err.println("エラー発生!!"); 97 e.printStackTrace(); 98 } 99 } 100 101 public static void send(String message, String now_ip) { 102 byte[] buffer = new byte[4096]; 103 DataOutputStream dataOutputStream = null; 104 try { 105 buffer = message.getBytes("UTF-8"); 106 107 for (String ip : client_list) { 108 if (ip == now_ip) continue; 109 dataOutputStream = new DataOutputStream(new Socket(ip.split("/")[1], PORT).getOutputStream()); 110 dataOutputStream.write(buffer); 111 dataOutputStream.flush(); 112 } 113 dataOutputStream.close(); 114 115 } catch (IOException e) { 116 // TODO 自動生成された catch ブロック 117 e.printStackTrace(); 118 } 119 } 120}

C#

1using System.Collections; 2using System.Collections.Generic; 3using System; 4using UnityEngine; 5using UnityEngine.UI; 6using System.Net.Sockets; 7using System.Text; 8using System.Net; 9using System.Threading.Tasks; 10 11public class ChatClient : MonoBehaviour { 12 13 // ゲームオブジェクト 14 public InputField input_field; 15 public GameObject content; 16 public GameObject chat_log; 17 18 // サーバー情報 19 private string server_ip_address = "192.168.0.25"; 20 private int port = 25252; 21 22 // クライアントの送信窓口 23 NetworkStream network_stream; 24 25 // 送信内容 26 private string send_text; 27 28 // 受信用 29 private TcpListener listener; 30 private float request_span = 10f; 31 private byte[] buffer = new byte[4096]; 32 33 34 // Start is called before the first frame update 35 void Start() { 36 37 network_stream = new TcpClient(server_ip_address, port).GetStream(); 38 Debug.Log(network_stream.Read(buffer, 0, buffer.Length)); 39 network_stream.Close(); 40 41 //Componentを扱えるようにする 42 input_field = input_field.GetComponent<InputField>(); 43 // 受信用 44 listener = new TcpListener(IPAddress.Parse(server_ip_address), port); 45 46 Task.Run(Listener); 47 } 48 49 public void InputText() { 50 //テキストにinputFieldの内容を反映 51 send_text = input_field.text; 52 } 53 54 // ボタンクリック時 55 public void NetworkRequest() { 56 // 接続要求 57 network_stream = new TcpClient(server_ip_address, port).GetStream(); 58 59 // 送信の内容をセット 60 if (send_text.Length == 0) return; 61 byte[] send_string = Encoding.UTF8.GetBytes(send_text); 62 63 // データを送信 64 network_stream.Write(send_string, 0, send_string.Length); 65 66 network_stream.Close(); 67 } 68 69 70 public void Listener() { 71 listener = new TcpListener(IPAddress.Parse(server_ip_address), port); 72 Debug.Log("監視開始1"); 73 74 listener.Start(); 75 Debug.Log("監視開始2"); 76 while (true) { 77 //接続要求があったら受け入れる 78 TcpClient client = listener.AcceptTcpClient(); 79 80 Debug.Log("きた!"); 81 82 // データを受信 83 network_stream.Read(buffer, 0, buffer.Length); 84 string message = Encoding.UTF8.GetString(buffer); 85 GameObject instance = Instantiate(chat_log); 86 instance.transform.parent = content.transform; 87 instance.transform.localScale = new Vector3(1, 1, 1); 88 instance.GetComponent<Text>().text = message; 89 90 // バッファリセット 91 buffer = new byte[4096]; 92 } 93 } 94 95} 96

そして、修正したコード動かしてみるとUnityから送信まではできたのですが、Javaからブロードキャストする際に以下のエラーメッセージが出てきて送信が出来ず、Unity側でも勿論反応がありません。
また、Unity側では起動時に"監視開始1"は表示されているのですが、その後"監視開始2"は表示されません。

サーバー稼働中... 1 IPアドレス:192.168.0.5:2019年07月09日03時13分43秒 [6ms] [壁]*´・ω・`)ノ コンニチハ.:゚+ java.net.ConnectException: 接続を拒否されました at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at java.net.Socket.connect(Socket.java:538) at java.net.Socket.<init>(Socket.java:434) at java.net.Socket.<init>(Socket.java:211) at ChatServer.send(ChatServer.java:109) at ChatServer.main(ChatServer.java:81)

色々調べてみましたが原因がわからず困っております...
あまりネットワークの通信に詳しくないのでわかる方がいらっしゃいましたら、どうかご教授いただきたいです。

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

ー 開発環境 ー
MacBook Pro (15-inch, 2016)
OS : macOS mojave
バージョン : Unity 2018.2.2f1
IPアドレス : 192.168.0.5

Raspberry Pi 3 Model B+
OS : Raspbian GNU/Linux 9
バージョン : Java SE 8
IPアドレス : 192.168.0.25

追記

Unity側で全くエラーが出てなかったので心配していなかったのですが、回答して頂いた内容を元にlistener.Start()にtry-catchを入れてみるとまさかのエラーが表示されておりました。。。
エラーを確認したばかりなので、今から原因を調べてみますが取り急ぎ追記させていただきました。

e.Messageの結果

The requested address is not valid in this context UnityEngine.Debug:Log(Object) ChatClient:Listener() (at Assets/Scripts/ChatClient.cs:80) System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

e.TargetSiteの結果

Void Bind(System.Net.EndPoint) UnityEngine.Debug:Log(Object) ChatClient:Listener() (at Assets/Scripts/ChatClient.cs:81) System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

e.StackTraceの結果

at System.Net.Sockets.Socket.Bind (System.Net.EndPoint localEP) [0x00043] in <3845a180c26b4889bc2d47593a665814>:0 at System.Net.Sockets.TcpListener.Start (System.Int32 backlog) [0x00044] in <3845a180c26b4889bc2d47593a665814>:0 at System.Net.Sockets.TcpListener.Start () [0x00000] in <3845a180c26b4889bc2d47593a665814>:0 at ChatClient.Listener () [0x00029] in /Users/reishisu/Documents/Unity/SocketTest/Assets/Scripts/ChatClient.cs:78 UnityEngine.Debug:Log(Object) ChatClient:Listener() (at Assets/Scripts/ChatClient.cs:80) System.Threading._ThreadPoolWaitCallback:PerformWaitCallback()

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

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

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

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

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

guest

回答2

0

Unity側は知りませんのでjava側から見たのみのお話です.
Unity側が接続待ち(監視接続2が表示される状態?)になっていなければ, java側の接続が拒否されたと言ってくるのは当然かと思います.
また, チャットでしたら最初のUnity→javaの接続を維持してメッセージのやり取りをすれば, わざわざ新たにjava→Unityの接続をしなくて済むのではないでしょうか.

投稿2019/07/08 19:06

編集2019/07/08 23:59
jimbe

総合スコア12545

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

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

reishisu

2019/07/08 20:00

回答していただきありがとうございます! なるほどです。 確かに、言われてみればListen状態じゃないのに受け付けてしまうのは逆に怖いですね。まずは、ちゃんと関数が実行されるように調べてみることにします! あと、接続を維持できるようにC#側で最初の一回だけ接続してClose関数を呼ばれないように消してみたのですが、2回目以降に送信できなくなってしまいました... 単純に、Closeしないだけではダメなのでしょうか?><
jimbe

2019/07/09 00:31

java 側も, 構造を変えなければ対応できません. 各クライアントからの受信は入力ストリームの read で待つことになりますので, マルチスレッドにする必要があり, キューを準備して送信用スレッドも必要かもしれません.
reishisu

2019/07/09 10:37

そうなんですね... TCPを詳しく理解せずに付け焼き刃で実装しているのが悪いのですが、今教えて頂いた話だとjava側でクライアント分の接続するパイプ的なのを並列で開いてそれぞれを双方向で常に通信できるようにし、クライアント側ではひたすらreadし続けるイメージでしょうか? あと、お話がそれてしまい申し訳ございませんが、私2年ほど前に学校でサーブレット/JSPを使ったサーバーサイドの構築をしたことがあります。 その中で今日、RESTという仕組みを見つけサーブレットのURIをAPIとして利用できれば難しい他言語間の処理をできるのでは?と考えましたが、これから作る予定のユーザ認証などでうまく利用できそうな感じがしたのですがいかがですかね?><
jimbe

2019/07/09 13:00

javaサーバ側では, ServerSocket.accept で返された Socket による Input/Output Stream は, 通信の異常発生やサーバ・クライアントどちらかが close しない限り繋がっていますので, ArrayList 等に保存しておけば使い続けられます. そして切断が起きれば送受信でエラー/例外が発生しますので, どの場合にどう対処(後始末)するかを考えておく必要があります. Unityクライアント側も, 受信に関しては何時サーバからデータが送られてくるのか分からないのですから, read し続ける必要はあるように思います. 機能がRESTで実現でき, かつRESTを利用したほうが作りやすいのでしたら, お使い頂ければよいかと思います. 底辺では現在のコードのようなことが行われているだけですから.
reishisu

2019/07/09 13:06

すごい腑に落ちて理解できました! 色々、丁寧に分かりやすく教えていただきありがとうございます>< では、次はJavaのSocketをArrayListで管理してそれでクライアント側でもエラー処理がうまくいくようでしたら、RESTでリクエストを送りSocketで応答するような仕組みづくりをしてみようと思います!
reishisu

2019/07/09 13:18

あ、申し訳ございません少しだけ疑問が、、、 SocketをArrayListで管理するのは理解できましたが、先ほどマルチスレッドと仰られたのはSocketの分だけ無限ループを回してクライアントだけでなくJavaの方でもひたすらクライアントごとにReadし続ける必要があるからでしょうか?
jimbe

2019/07/09 13:28

そうですね. より正確には, Socket(OutputStream)をリストとして必要なのは送信側ですので, 受信側は「クライアント毎のスレッド」が1つずつ持てば(そしてInputStream.readし続ければ)良いかと思います.
jimbe

2019/07/09 13:35

なお, 私の回答はかなり「イメージ」でお伝えしています. コードで示せれば『百聞は一見に…』なのですが. マルチスレッドはjava内でも色々修正・変更が繰り返されている機能ですので, 本来のマルチスレッドの難しさと共にjavaでの難しさもあります. 無責任ですが, ドキュメントやネットの記事をよくお探しになってお使いください(_ _;
reishisu

2019/07/09 13:54

なるほどです>< 送信の際は、メインスレッドのみでforループを利用して必要に応じ適宜送信するのでマルチスレッドの必要性低く、クライアントからの受信の際は同時に1つのサーバーにほぼ同じタイミングでアクセスする可能性があるのでThreadで同時アクセスに対応し、さらにサーバー自体を排他制御する必要があるのですね。 一応、Webアプリの構築で知り合いからDOS攻撃まがいの大量アクセスをされたことがありMySQLを利用する際にSynchronizedにかなりお世話になった記憶があるのでもう少し深掘りしながら、慎重に実装していこうと思います((+_+)) 私はお世辞にも優秀とは言えない学生なのですが、まさかここまで進展できるとは思っておらずかなり驚いております。 本当にありがとうございました(>_<;)
guest

0

自己解決

あまり、気持ちよくないのですがC#の
listener = new TcpListener(IPAddress.Parse(server_ip_address), port);
を全てから受け取れるように
listener = new TcpListener(IPAddress.Any, port);
と変更するとJavaの方からもメッセージを受け取ることができました。
もしかして、ルーターを経由して使っているのでラズパイではなくmacに一番近いルーターのIPアドレスが必要だと推察してルーターのIPを設定してみるとエラーのままだったので、Anyでできたのが少し気持ち悪い感じでした。

自己解決したコードは以下になります。
(今回は通信だけの質問だったので、別スレッドで実行しているので受け取ったメッセージをメインスレッドにデータの送信ができていないので完全に完成はしておりません。)

C#のコード
回答して頂いたjimbe様、解決のヒントを下さり本当にありがとうございました。

追記

一応、目的のとりあえず動くコードは(多分)作れたので追記させて頂きます。
Javaのコード
C#のコード

追記(2019年7月10日)

Javaのコードを2つに分けることでうまく、排他制御することに成功しました!!
サーバー側でアクセスされる度にクライアントのIPアドレスを確認し、クライアントのIPアドレスを管理しているリストにあればそのままThreadを非同期で実行させており、なければリストに追加して同じくThreadを非同期で実行させております。
Threadの中では、メインスレッドにあるbroadcast関数をsynchronized修飾子をつけ排他制御しながら実行しているのでうまくスレッドの生成順に実行させることができ、上手くできたかなぁと思っております。
また、アプリを落とした時の切断エラーに関してもエラーをcatchした瞬間に当該IPをリストから削除することで他のスレッドに干渉せずに出来ました!

Java

1package raspi_server; 2 3import java.io.DataOutputStream; 4import java.io.IOException; 5import java.net.ServerSocket; 6import java.net.Socket; 7import java.util.ArrayList; 8 9/** 10 * ラズパイ上で動かすチャットのサーバークラスです 11 * @author reishisu 12 */ 13public class ChatServer { 14 15 /** 16 * ソケット通信を行うポート 17 */ 18 private static final int PORT = 25252; 19 /** 20 * チャットサーバーの窓口 21 */ 22 private static ServerSocket server_socket; 23 24 25 /** 26 * 接続してきたIPアドレス 27 */ 28 private static ArrayList<Socket> socket_list = new ArrayList<>(); 29 /** 30 * チャットのナンバー 31 */ 32 private static int chat_number = 1; 33 34 /** 35 * メイン関数 36 * @param args コマンドライン引数 37 */ 38 public static void main(String[] args) { 39 try { 40 // 既にサーバーが建っていない時サーバーソケットの生成 41 if (server_socket == null) { 42 server_socket = new ServerSocket(PORT); 43 System.out.println("サーバー稼働中..."); 44 } 45 // サーバー稼働 46 while (true) { 47 // クライアントからの接続が来るまで待機 48 Socket client_socket = server_socket.accept(); 49 // 新規か確認 50 boolean is_new = true; 51 // 新規のIPがないかを走査する 52 for(Socket client : socket_list) { 53 if ( client.getInetAddress().toString().equals(client_socket.getInetAddress().toString())) { 54 System.out.println("同じとこからきてる!"); 55 new ClientReciever(client_socket).start(); 56 is_new = false; 57 } 58 } 59 // 新規の場合 60 if (is_new) { 61 // ソケットリストに追加 62 socket_list.add(client_socket); 63 // 新規ソケット用のスレッドを実行 64 new ClientReciever(client_socket).start(); 65 System.out.println("新規さん入ります!\nIPアドレス:" + client_socket.getInetAddress().toString() + "\n合計接続数:" + socket_list.size()); 66 } 67 } 68 } 69 catch (Exception e) { 70 System.err.println("エラー発生!!"); 71 e.printStackTrace(); 72 } 73 } 74 75 /** 76 * クライアントにメッセージをブロードキャストするための関数 77 * @param message 送信文字列 78 */ 79 public static synchronized void broadcast(String message) { 80 byte[] buffer = new byte[4096]; 81 DataOutputStream dataOutputStream = null; 82 try { 83 buffer = message.getBytes("UTF-8"); 84 85 for (Socket client : socket_list) { 86 try { 87 dataOutputStream = new DataOutputStream(new Socket(client.getInetAddress().toString().split("/")[1], PORT).getOutputStream()); 88 dataOutputStream.write(buffer); 89 dataOutputStream.flush(); 90 } catch (Exception e) { 91 System.out.println(client.getInetAddress().toString().split("/")[1] + "との接続が切れました"); 92 socket_list.remove(client); 93 } 94 } 95 } catch (IOException e) { e.printStackTrace(); } 96 } 97 98 /** 99 * チャットナンバーを返す 100 * @return 現在のチャットナンバー 101 */ 102 public static synchronized int getChat_number() { 103 chat_number++; 104 return chat_number-1; 105 } 106} 107

Java

1package raspi_server; 2 3import java.io.DataInputStream; 4import java.net.Socket; 5import java.text.SimpleDateFormat; 6import java.util.Date; 7 8/** 9 * チャットのアプリケーションクラスです 10 * @author reishisu 11 */ 12public class ClientReciever extends Thread { 13 14 /** 15 * 受信する対象のクライアント 16 */ 17 private Socket client; 18 /** 19 * クライアントのデータ受信窓口 20 */ 21 private DataInputStream data_input_stream; 22 /** 23 * 無限ループなのでフラグを使って意図的にスレッドを終了させる 24 */ 25 public boolean do_thread_finish; 26 /** 27 * // タイムスタンプのテンプレート 28 */ 29 SimpleDateFormat time_stamp = new SimpleDateFormat("yyyy年MM月dd日HH時mm分ss秒"); 30 31 32 /** 33 * コンストラクタ 34 * @param client 受信の対応をするクライアント用の窓口 35 */ 36 public ClientReciever(Socket client) { 37 try { 38 System.out.println("ClientReciever Called!!"); 39 this.client = client; 40 this.data_input_stream = new DataInputStream(client.getInputStream()); 41 } 42 catch (Exception e) { 43 System.out.println("スレッド生成時にエラーが発生しました..."); 44 e.printStackTrace(); 45 } 46 } 47 48 /** 49 * ひたすらデータの受信を行う 50 */ 51 public void run() { 52 // 文字列を受け取るバッファ 53 byte[] buffer = new byte[4096]; 54 // 受信文字列 55 String send_message = ""; 56 // スレッド終了の合図が出るまで実行 57 while(!do_thread_finish) { 58 try { 59 int read_resuld = data_input_stream.read(buffer); 60 // データの受信が確認されなかった時は実行されない 61 if (read_resuld == 0 || read_resuld == -1) continue; 62 // 受信時間の計測を開始 63 long start_time = System.currentTimeMillis(); 64 // 受信した文字列 65 String recieve_string = new String(buffer, "UTF-8"); 66 // 計測終了 67 long end_time = System.currentTimeMillis(); 68 // 受信した文字列に付加情報をつけて送信文字列を作成 69 send_message = new StringBuilder().append(ChatServer.getChat_number()).append(" IPアドレス:").append(client.getInetAddress().toString().split("/")[1]) 70 .append(":").append(time_stamp.format(new Date())).append(" [").append((end_time - start_time)) 71 .append("ms]\n").append(recieve_string).append("\n").toString(); 72 // 送信文字列を表示 73 System.out.println(send_message); 74 // 登録リストへ送信文字列をブロードキャストする 75 ChatServer.broadcast(send_message); 76 do_thread_finish = !do_thread_finish; 77 } 78 catch (Exception e) { 79 e.printStackTrace(); 80 // 受信した文字列に付加情報をつけて送信文字列を作成 81 send_message = new StringBuilder().append(ChatServer.getChat_number()).append(" IPアドレス:").append(client.getInetAddress().toString().split("/")[1]) 82 .append(":").append(time_stamp.format(new Date())).append(" 9999[ms]\n受信失敗...\n").toString(); 83 // 送信文字列を表示 84 System.out.println(send_message); 85 // 登録リストへ送信文字列をブロードキャストする 86 ChatServer.broadcast(send_message); 87 do_thread_finish = !do_thread_finish; 88 } 89 } 90 } 91} 92

C#

1using System.Collections; 2using System.Collections.Generic; 3using System; 4using UnityEngine; 5using UnityEngine.UI; 6using System.Net.Sockets; 7using System.Text; 8using System.Net; 9using System.Threading.Tasks; 10using System.Threading; 11 12public class ChatClient : MonoBehaviour { 13 14 // ゲームオブジェクト 15 public InputField input_field; 16 public GameObject content; 17 public GameObject chat_log; 18 19 public static string a; 20 21 //おまじない 22 private SynchronizationContext context; 23 24 // サーバー情報 25 private string server_ip_address = "192.168.0.25"; 26 private int port = 25252; 27 28 // クライアントの送信窓口 29 NetworkStream network_stream; 30 31 // 送信内容 32 private string send_text; 33 34 // 受信用 35 private TcpListener listener; 36 private float request_span = 10f; 37 private byte[] buffer = new byte[4096]; 38 39 40 // Start is called before the first frame update 41 void Start() { 42 43 context = SynchronizationContext.Current; 44 45 //Componentを扱えるようにする 46 input_field = input_field.GetComponent<InputField>(); 47 48 // 監視 49 Task.Run(Listener); 50 } 51 52 private void Update() { 53 if (a != "") { 54 GameObject instance = Instantiate(chat_log); 55 instance.transform.parent = content.transform; 56 instance.transform.localScale = new Vector3(1, 1, 1); 57 instance.GetComponent<Text>().text = a; 58 a = ""; 59 } 60 } 61 62 public void InputText() { 63 //テキストにinputFieldの内容を反映 64 send_text = input_field.text; 65 } 66 67 // ボタンクリック時 68 public void NetworkRequest() { 69 // 接続要求 70 network_stream = new TcpClient(server_ip_address, port).GetStream(); 71 72 // 送信の内容をセット 73 if (send_text.Length == 0) return; 74 byte[] send_string = Encoding.UTF8.GetBytes(send_text); 75 76 // データを送信 77 network_stream.Write(send_string, 0, send_string.Length); 78 79 network_stream.Close(); 80 } 81 82 83 public void Listener() { 84 85 SynchronizationContext.SetSynchronizationContext(context); 86 87 listener = new TcpListener(IPAddress.Any, port); 88 89 Debug.Log("監視開始1"); 90 91 try { 92 listener.Start(); 93 } 94 catch (Exception e) { 95 Debug.Log(e.Message); 96 Debug.Log(e.TargetSite); 97 Debug.Log(e.StackTrace); 98 } 99 100 Debug.Log("監視開始2"); 101 while (true) { 102 //接続要求があったら受け入れる 103 TcpClient client = listener.AcceptTcpClient(); 104 105 Debug.Log("きた!"); 106 107 network_stream = client.GetStream(); 108 109 // データを受信 110 network_stream.Read(buffer, 0, buffer.Length); 111 string message = Encoding.UTF8.GetString(buffer); 112 Debug.Log(message); 113 a = message; 114 115 // バッファリセット 116 buffer = new byte[4096]; 117 118 network_stream.Close(); 119 } 120 } 121 122} 123

投稿2019/07/08 21:04

編集2019/07/09 20:21
reishisu

総合スコア39

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問