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

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

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

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

Java

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

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

2253閲覧

byte[]→string→string[]→doubleについて

P5_USER

総合スコア73

C#

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

Java

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

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

1クリップ

投稿2017/11/28 04:33

編集2017/11/28 06:12

###前提・実現したいこと
前提条件①:C#にて4つのdouble型変数をスペース区切りでstring型変数にしている
前提条件②:そのstringをUTF8でエンコードしてbyte[]としている。
前提条件③:UDPでbyte[]を送信している(ここまではC#の出来事)
前提条件④:以下URLを参考にprocessingでbyte[]を受け取っている(はず)。
URL:http://memorandums.hatenablog.com/entry/2016/11/08/203610

目標①:受け取ったバイト配列をスペース区切りで4つに分割してprocessing側で新規に作成したdouble型変数(ここではA_nowとか)に格納する。
目標②:updateTime()での値更新。

今回C#にさせる役割はデータの仲介です。
通信の全体図

###発生している問題・エラーメッセージ
変数の値(A_now,B_now,C_now,D_now,A_before,B_before,C_before,D_before)
が変わっていない

ずっと0.0のまま
Bashoで確認
Bashoについて:https://www.youtube.com/watch?v=8Z23xNN7IGU

###該当のソースコード

C#

1using System; 2using System.IO; 3using System.Collections.Generic; 4using System.Linq; 5using System.Text; 6using System.Threading.Tasks; 7using System.Runtime.InteropServices; 8 9namespace test4_P5.ver 10{ 11 [StructLayout(LayoutKind.Sequential)] 12 struct STRUCTURE 13 { 14 public double AA; 15 public double BB; 16 public double CC; 17 public double D1; 18 public double D2; 19 }; 20 21 class Program 22 { 23 static void Main(string[] args) 24 { 25 System.String name; 26 DateTime dt = System.DateTime.Now; 27 name = @"C:\Users\hogehoge\Desktop\フォルダ\" + dt.ToString("tthh時mm分ss秒") + ".csv"; 28 System.IO.StreamWriter w = new System.IO.StreamWriter(name, false); 29 System.Threading.Thread.Sleep(5000); 30 w.Write("time,AA,AA,BB,BB,CC,CC,D1,D2,DD\n"); 31 32 //バインドするローカルIPとポート番号 33 string localIpString = "〇.〇.〇.〇"; 34 //string localIpString = "127.0.0.1"; 35 36 System.Net.IPAddress localAddress = 37 System.Net.IPAddress.Parse(localIpString); 38 int localPort = 12000; 39 40 //UdpClientを作成し、ローカルエンドポイントにバインドする 41 System.Net.IPEndPoint localEP = 42 new System.Net.IPEndPoint(localAddress, localPort); 43 System.Net.Sockets.UdpClient udp = 44 new System.Net.Sockets.UdpClient(localEP); 45 46 //データを送信するリモートホストとポート番号 47 string remoteHost = "172.0.0.1"; 48 int remotePort = 60000; 49 50 //UdpCliantオブジェクトを作成する。 51 System.Net.Sockets.UdpClient client = 52 new System.Net.Sockets.UdpClient(); 53 54 DateTime startdt = System.DateTime.Now; 55 56 //Processingにデータを渡すための前処理 57 double AA, BB, CC, DD; 58 59 for (; ; ) 60 { 61 //データを受信する 62 System.Net.IPEndPoint remoteEP = null; 63 byte[] rcvBytes = udp.Receive(ref remoteEP); 64 //データを文字列に変換する 65 FSSM rcvMsg = new STRUCTURE(); 66 //Marshal.PtrToStructure(rcvBytes, typeof(STRUCTURE)); 67 68 //string rcvMsg = System.Text.Encoding.UTF8.GetString(rcvBytes); 69 70 //↓[追加]バイト配列を構造体にコピーする。 71 IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(rcvMsg)); 72 73 Marshal.Copy(rcvBytes, 0, ptr, Marshal.SizeOf(rcvMsg)); 74 rcvMsg = (STRUCTURE)Marshal.PtrToStructure(ptr, typeof(STRUCTURE)); 75 Console.WriteLine(Marshal.SizeOf(rcvMsg)); 76 Marshal.FreeHGlobal(ptr); 77 78 //送信するデータを作成する 79 AA = rcvMsg.AA; 80 BB = rcvMsg.BB; 81 CC = rcvMsg.CC; 82 DD = ((rcvMsg.D1 + rcvMsg.D2) / 2); 83 84 string sendMsg = AA + " " + BB + " " + CC + " " + DD; 85 byte[] sendBytes = System.Text.Encoding.UTF8.GetBytes(sendMsg); 86 87 //リモートホストを指定してデータを転送する 88 client.Send(sendBytes, sendBytes.Length, remoteHost, remotePort); 89 90 //"exit"を受信したら終了 91 if (rcvMsg.Equals("exit")) 92 { 93 w.Close(); 94 break; 95 } 96 } 97 98 //UdpClientを閉じる 99 udp.Close(); 100 Console.WriteLine("終了しました。"); 101 Console.ReadLine(); 102 w.Close(); 103 104 client.Close(); 105 } 106 } 107} 108

processing

1import hypermedia.net.*; //<>// 2UDP udp; 3//Basho basho; 4//Double_Absolute D_ABS; 5 6int dW, dH, dW30, dW15, dW10, dH30, dH15, dH10 ; 7 8//現在値 9double A_now = 0.0; 10double B_now = 0.0; 11double C_now = 0.0; 12double D_now = 0.0; 13 14//1フレーム前の値 15double A_before; 16double B_before; 17double C_before; 18double D_before; 19 20 21void setup() { 22 fullScreen(); 23 frameRate(60);//フレームレートを設定 24 dW=displayWidth; 25 dH=displayHeight; 26 27 udp = new UDP (this, 60000); 28 udp.listen(true); 29 //basho = new Basho(this); 30} 31 32void receive (byte[] data, String ip, int port) { 33 String message = new String(data); 34 String[] rcvMSG = splitTokens(message, " "); 35 36 A_now = Double.parseDouble(rcvMSG[0]); 37 B_now = Double.parseDouble(rcvMSG[1]); 38 C_now = Double.parseDouble(rcvMSG[2]); 39 D_now = Double.parseDouble(rcvMSG[3]); 40 //println( "receive: \""+message+"\" from "+ip+" on port "+port ); 41} 42 43 44void draw() { 45 background(0, 0, 0);//黒色背景 46 smooth();//滑らかな描写 47 stroke(0, 255, 0);//線の色:緑 48 fill(0, 255, 0);//充填の色:緑 49 scale(1, -1);//x軸右側正&y軸上側正 50 translate(dW/2, -dH/2);//画面中央に原点移動 51 updateTime(); 52} 53 54void updateTime() {//一個前の値を差分処理用に格納 55 A_before = A_now; 56 B_before = B_now; 57 C_before = C_now; 58 D_before = D_now; 59} 60 61class Double_Absolute {//abs()がdoubleをサポートしていないのでdouble用に作成 62 double ABS (double b) 63 { 64 if (b<0) 65 { 66 b = -b; 67 } 68 return b; 69 } 70}

###試したこと
デバッグモードでの変数確認や先程記載したBashoでのリアルタイム変数遷移の確認。
↑でもやっぱり値が変わらず...

もしかして,送信と受信のヘルツがあってないとダメ?

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/11/28 04:40

そもそもAPサーバーに到達しているかどうか
P5_USER

2017/11/28 04:48

初めてAPサーバーなる言葉を目にしたのですが,1つ目のURLに記載されていたUDP通信を模倣&改良したので,全く考えておりませんでした。実際に到達しているか否かというのは,println等で確認をしたりするのでしょうか。
coco_bauer

2017/11/28 07:52

コードのどこかにUDPからデータを読み出す "udp.receive"が必要だと思うのですが、見当たりません。 質問のコードにあるreceiveメソッドの第一引数のバイト列 dataの値は、どこから得ているのですか。
P5_USER

2017/11/28 07:57 編集

前提条件④でのURLを参考にしており,実際に通信に成功したのですが,udp.receiveが必要なのですね。 私も調べてみます。
guest

回答1

0

ベストアンサー

asahina1979さんのコメントがあたりのような・・・

多分、講師の方が公開しておられる下のページですよね・・・
http://memorandums.hatenablog.com/entry/2016/11/08/203610

このプログラムの場合、Processing側でUDPポート(6000)から通信が入ってくるのを常に待っていて、受信したらreceiveメソッドが呼び出されるという仕組みのようです。上記ページのコードと見比べたところ特に違いは見つからなかったのでおそらくC#側からProcessingへ通信が届いてないような気がします。

確認方法として以下をやってみてはいかがでしょうか?

Processing

1... 2int receiveCount = 0; // 受信回数を記録する変数をメソッドの外側に定義 3... 4 5void receive (byte[] data, String ip, int port) { 6 // ここで受信回数をインクリメント 7 receiveCount++; 8 // 以下は元のコードのとおり 9 String message = new String(data); 10 ... 11}

BashoのgithubのReadme.mdには非常にあっさりと「大域変数の監視とか」という程度のことしか書いてないのでよくわかりませんが、もし上記receiveCountの値がBashoで観察できるなら通信が届いているかどうかすぐわかると思います。

もし0のまま変わらないならC#側の問題と思いますのでそちらに着目して調べてみてください。

投稿2017/11/28 05:18

KSwordOfHaste

総合スコア18394

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

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

P5_USER

2017/11/28 05:29

早速試してみました。 Bashoで確認してみたところ,receiveCountは1の値でその後増えていきませんでした。 行動としては。setup()のように1回だけ動いて,と同じなのでしょうか。
P5_USER

2017/11/28 05:30

訂正します,1ではなく0でした。 初期値を打ち間違えていました。
KSwordOfHaste

2017/11/28 05:34

やはりそうですか。C#からUDP通信が届いてないのですね。C#側または通信環境の問題だと思います。なお、ProcessingとC#を同一PC上で動かしているのなら通信自体に難しい点はないですが違うPCで動かしているならぐっと難しくなるかも知れません・・・ポート開放とかIPアドレスが正しいかとかややこしい問題がからんでくる気がします。
P5_USER

2017/11/28 05:53

ProcessingとC#は同一PC(ローカルループバック)で動かしています。 C#のソースコードを記載いたしました。ご確認いただければと思います。
KSwordOfHaste

2017/11/28 05:59

あの・・・C#側でどういう処理をしているか説明してみてください。何をしているかわからないではプログラムは作れませんよ?C#で12000ポートからデータを受信しようとしてますが、このポートへ送信する人は誰なのでしょう。自分にはそれが分かりませんでした。
P5_USER

2017/11/28 06:05

失礼しました。 シミュレーターがありまして,そこからモデルの座標や速度,加速度といったデータを構造体でまとめてUDPで送られてきます。この時,構造体を受けるものがこのC#でのプログラムになります。 正確には,シミュレーターを取りまとめているホストコンピューターがあります。 そのコンピューターがLANケーブルでリスナーPCの12000盤ポートに構造体を送り付けています。 今回,C#のプログラムではホストPCから出てきたデータをprocessingにリレーする仲介役をさせる目的で作成しています。
KSwordOfHaste

2017/11/28 06:11

なるほど。自分はC#でUDPを送信したことが一度もないのでもしやるなら調べないと正しさが確認できません。しかしデバッグの仕方としては本回答と同様で、Console.WriteLineなどで「受信したこと」「送信したこと」がわかるようにデバッグプリントを入れるのが一番わかりやすいと思いますよ?
KSwordOfHaste

2017/11/28 06:14 編集

その際に、受信・送信がうまくいったかどうかがわかるようなもの(例えばAPIを呼び出した時その戻り値でわかるなら戻り値)をWriteLineで印字してやるとより確実な情報がつかめると思います。この辺りはどんなプログラムをデバッグする場合でも同じ手法です。
umyu

2017/11/28 06:20

横からレス失礼します、string remoteHost = "172.0.0.1";ですが、ローカルホストは127.0.0.1ですが、それは大丈夫ですか?
P5_USER

2017/11/28 06:30

!!! その通りです。 ローカルループバックだけ,暗記で記述していたのが仇となりました。 本当にどうしようもない凡ミスでした... 実行したところ,Processing側でのBashoウィンドウでちゃんと,変数の推移が確認できました。 umyuさん。ご指摘いただきありがとうございました。 asahina1979さん,KSwordOfHasteさんのご指摘も,私が他にも学ぶべき情報を教えていただきました。 重ねてお礼申し上げます。
KSwordOfHaste

2017/11/28 06:34 編集

たしかにそうですね! もし172.0.0.1が割り当てられてないIPだとUDPなので送信できないまま何もエラーを検知できないということになるんでしょうか。そこは自分も知りたい気がします。==>そこは本件には関係ないですね。失礼しました。
P5_USER

2017/11/28 06:44

確か,UDPの場合だとホスト側は受信の確認をクライアントから求めないので(というより,求めないようにして通信速度を速めている),エラーが出ない筈です。 今回は,その仕様に見事にハマってしまいました^^;
KSwordOfHaste

2017/11/28 06:54

愚問でした。パケット出す前にエラーがわかるケースがあるのかなとふと感じたのですが自分で調べるべきでした!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問