Unity UDP通信を受信する
あいさつ
どうも、はかせです。
何気なくアクセス解析を見てたらですね
以前上げたTCP通信の記事がトップになってました。
ということで今日はUDPやっていきますよ。
(別にこのためにやってたわけじゃないけど)
ちなみに今回は受信だけです。
実装内容
今回はスマホとPCでUDP通信を行い
加速度センサーの値と姿勢センサーの値を取得します。
スマホからのデータ送信には
「ZIG SIM」というアプリを使います。
このアプリはスマホの各種センサの値を色んな通信方法やデータ形式で送信できるアプリです。
今回はUDP通信でJSONを送ります。
JSONの扱いはMiniJSONとJsonNodeを使っています。
コード
UdpClientを使いデータを取得した後
JsonNodeを使ってJSONにパースします。
using System; using System.Text; using System.Net; using System.Net.Sockets; public class UdpReceiver : IDisposable { UdpClient mUdp; //ソケット通信に何か問題が発生したときのコールバック public Action<SocketException> SocketExceptionCallBack; //UdpClientがDisposeされているときのコールバック public Action<ObjectDisposedException> ObjectDisposedExceptionCallBack; /*以下アプリ依存のコールバック*/ //加速度センサーのコールバック public Action<double, double, double> AccelCallBack; //姿勢センサーのコールバック public Action<double, double, double, double> QuaternionCallBack; /// <summary> /// Udp通信を開始する /// </summary> /// <param name="localIpString">IPアドレス</param> /// <param name="localPort">ポート番号</param> public void Start(string localIpString,int localPort) { IPAddress localAddress = IPAddress.Parse(localIpString); IPEndPoint localEP = new IPEndPoint(localAddress, localPort); mUdp = new UdpClient(localEP); mUdp.BeginReceive(UDPReceive, mUdp); } public void Dispose() { mUdp.Dispose(); } /// <summary> /// 受信処理 /// </summary> /// <param name="res"></param> void UDPReceive(IAsyncResult res) { UdpClient getUdp = (UdpClient)res.AsyncState; IPEndPoint ipEnd = null; try { //バイトデータを取得 byte[] getByte = getUdp.EndReceive(res, ref ipEnd); //アスキーコードで文字列に変換 string text = Encoding.ASCII.GetString(getByte); //JSONをパース 今回はMiniJSON+JsonNodeを使ってる JsonNode jsonNode = JsonNode.Parse(text); //加速度センサーの値を取得 double ax = jsonNode["sensordata"]["accel"]["x"].Get<double>(); double ay = jsonNode["sensordata"]["accel"]["y"].Get<double>(); double az = jsonNode["sensordata"]["accel"]["z"].Get<double>(); //姿勢センサーの値を取得 double qutX = jsonNode["sensordata"]["quaternion"]["x"].Get<double>(); double qutY = jsonNode["sensordata"]["quaternion"]["y"].Get<double>(); double qutZ = jsonNode["sensordata"]["quaternion"]["z"].Get<double>(); double qutW = jsonNode["sensordata"]["quaternion"]["w"].Get<double>(); //コールバックに流す AccelCallBack(ax, ay, az); QuaternionCallBack(qutX, qutY, qutZ, qutW); } catch (SocketException ex) { SocketExceptionCallBack(ex); return; } catch (ObjectDisposedException ex) { ObjectDisposedExceptionCallBack(ex); return; } //もう一回受信 getUdp.BeginReceive(UDPReceive, getUdp); } }
Startを呼び出すことでUdpClientを作成し、
受信を開始します。
StartにはIPアドレスとポート番号を渡します。
IPアドレスはcmdからipconfigで調べられます。
ポート番号はなんでもいいですが、
不安な人はnetstatで使おうとしているポートが空いてるか
調べるといいです。
Startを呼び出した後はデータを受信したタイミングで
・受信停止
・バイトデータ取得
・バイトデータをアスキーコードでエンコード
・エンコード文字列をJSONにパース
・JSONからデータを取得し各コールバックを起動
・再度受信を開始
という処理を行います。
実行環境
通信を扱うものなのでちょっとだけ
意識しなきゃいけないことがあります。
・スマホとPCを同一LANにつなぐ
・Unity側はビルドした実行ファイルを使う
一つ目はまぁそらそうだって話なんですが、
二つ目は意外とハマりそうです。(ハマりました)
詳しい原理やら理屈やらは知りませんが、
エディタ実行でやるとUDPのパケットが叩き潰されます。
(マジUnityファッ○)
なのでビルドしましょう。
Build and RunならCtrl+Bでできますから(Windows)
あとがき
今回はUnityでUDP通信でした。
ハマりどころはありますが、
そこさえ回避できればそんな難しくはないです。
あと今回やるうえで初めて知った「ZIG SIM」
ぶっちゃけめちゃめちゃ強いアプリだと思います。
これとUnityがあればなんちゃってIoTが簡単に作れますね。
今回の記事が良ければスターやコメント等よろしくお願いします。
それでは今回はこの辺でノシ