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

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

ただいまの
回答率

91.36%

  • Java

    10446questions

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

  • C#

    4754questions

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

  • Processing

    166questions

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

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

解決済

回答 1

投稿 2017/11/28 13:33 ・編集 2017/11/28 15:12

  • 評価
  • クリップ 1
  • VIEW 110

P5_USER

score 6

前提・実現したいこと

前提条件①: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

該当のソースコード

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace test4_P5.ver
{
    [StructLayout(LayoutKind.Sequential)]
    struct STRUCTURE
    {
        public double AA;
        public double BB;
        public double CC;
        public double D1;
        public double D2;
    };

    class Program
    {
        static void Main(string[] args)
        {
            System.String name;
            DateTime dt = System.DateTime.Now;
            name = @"C:\Users\hogehoge\Desktop\フォルダ\" + dt.ToString("tthh時mm分ss秒") + ".csv";
            System.IO.StreamWriter w = new System.IO.StreamWriter(name, false);
            System.Threading.Thread.Sleep(5000);
            w.Write("time,AA,AA,BB,BB,CC,CC,D1,D2,DD\n");

            //バインドするローカルIPとポート番号
            string localIpString = "〇.〇.〇.〇";
            //string localIpString = "127.0.0.1";

            System.Net.IPAddress localAddress =
                System.Net.IPAddress.Parse(localIpString);
            int localPort = 12000;

            //UdpClientを作成し、ローカルエンドポイントにバインドする
            System.Net.IPEndPoint localEP =
                new System.Net.IPEndPoint(localAddress, localPort);
            System.Net.Sockets.UdpClient udp =
                new System.Net.Sockets.UdpClient(localEP);

            //データを送信するリモートホストとポート番号
            string remoteHost = "172.0.0.1";
            int remotePort = 60000;

            //UdpCliantオブジェクトを作成する。
            System.Net.Sockets.UdpClient client =
                new System.Net.Sockets.UdpClient();

            DateTime startdt = System.DateTime.Now;

            //Processingにデータを渡すための前処理
            double AA, BB, CC, DD;

            for (; ; )
            {
                //データを受信する
                System.Net.IPEndPoint remoteEP = null;
                byte[] rcvBytes = udp.Receive(ref remoteEP);
                //データを文字列に変換する
                FSSM rcvMsg = new STRUCTURE();
                //Marshal.PtrToStructure(rcvBytes, typeof(STRUCTURE));

                //string rcvMsg = System.Text.Encoding.UTF8.GetString(rcvBytes);

                //↓[追加]バイト配列を構造体にコピーする。
                IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(rcvMsg));

                Marshal.Copy(rcvBytes, 0, ptr, Marshal.SizeOf(rcvMsg));
                rcvMsg = (STRUCTURE)Marshal.PtrToStructure(ptr, typeof(STRUCTURE));
                Console.WriteLine(Marshal.SizeOf(rcvMsg));
                Marshal.FreeHGlobal(ptr);

                //送信するデータを作成する
                AA = rcvMsg.AA;
                BB = rcvMsg.BB;
                CC = rcvMsg.CC;
                DD = ((rcvMsg.D1 + rcvMsg.D2) / 2);

                string sendMsg = AA + " " + BB + " " + CC + " " + DD;
                byte[] sendBytes = System.Text.Encoding.UTF8.GetBytes(sendMsg);

                //リモートホストを指定してデータを転送する
                client.Send(sendBytes, sendBytes.Length, remoteHost, remotePort);

                //"exit"を受信したら終了
                if (rcvMsg.Equals("exit"))
                {
                    w.Close();
                    break;
                }
            }

            //UdpClientを閉じる
            udp.Close();
            Console.WriteLine("終了しました。");
            Console.ReadLine();
            w.Close();

            client.Close();
        }
    }
}
import hypermedia.net.*; //<>//
UDP udp;
//Basho basho;
//Double_Absolute D_ABS;

int dW, dH, dW30, dW15, dW10, dH30, dH15, dH10 ;

//現在値
double A_now = 0.0;
double B_now = 0.0;
double C_now = 0.0;
double D_now = 0.0;

//1フレーム前の値
double A_before;
double B_before;
double C_before;
double D_before;


void setup() {
  fullScreen();
  frameRate(60);//フレームレートを設定
  dW=displayWidth;
  dH=displayHeight;

  udp = new UDP (this, 60000);
  udp.listen(true);
  //basho  = new Basho(this);
}

void receive (byte[] data, String ip, int port) {
  String message = new String(data);
  String[] rcvMSG = splitTokens(message, " ");

  A_now = Double.parseDouble(rcvMSG[0]);
  B_now = Double.parseDouble(rcvMSG[1]);
  C_now = Double.parseDouble(rcvMSG[2]);
  D_now = Double.parseDouble(rcvMSG[3]);
  //println( "receive: \""+message+"\" from "+ip+" on port "+port );
}


void draw() {
  background(0, 0, 0);//黒色背景
  smooth();//滑らかな描写
  stroke(0, 255, 0);//線の色:緑
  fill(0, 255, 0);//充填の色:緑
  scale(1, -1);//x軸右側正&y軸上側正
  translate(dW/2, -dH/2);//画面中央に原点移動
  updateTime();
}

void updateTime() {//一個前の値を差分処理用に格納
  A_before = A_now;
  B_before = B_now;
  C_before = C_now;
  D_before = D_now;
}

class Double_Absolute {//abs()がdoubleをサポートしていないのでdouble用に作成
  double ABS (double b)
  {
    if (b<0)
    {
      b = -b;
    }
    return b;
  }
}

試したこと

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asahina1979

    2017/11/28 13:40

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

    キャンセル

  • P5_USER

    2017/11/28 13:48

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

    キャンセル

  • coco_bauer

    2017/11/28 16:52

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

    キャンセル

  • P5_USER

    2017/11/28 16:57 編集

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

    キャンセル

回答 1

checkベストアンサー

+1

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

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

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

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

...
int receiveCount = 0; // 受信回数を記録する変数をメソッドの外側に定義
...

void receive (byte[] data, String ip, int port) {
  // ここで受信回数をインクリメント
  receiveCount++;
  // 以下は元のコードのとおり
  String message = new String(data);
  ...
}

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

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

投稿 2017/11/28 14:18

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/28 14:29

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

    キャンセル

  • 2017/11/28 14:30

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

    キャンセル

  • 2017/11/28 14:34

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

    キャンセル

  • 2017/11/28 14:53

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

    キャンセル

  • 2017/11/28 14:59

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

    キャンセル

  • 2017/11/28 15:05

    失礼しました。
    シミュレーターがありまして,そこからモデルの座標や速度,加速度といったデータを構造体でまとめてUDPで送られてきます。この時,構造体を受けるものがこのC#でのプログラムになります。

    正確には,シミュレーターを取りまとめているホストコンピューターがあります。
    そのコンピューターがLANケーブルでリスナーPCの12000盤ポートに構造体を送り付けています。

    今回,C#のプログラムではホストPCから出てきたデータをprocessingにリレーする仲介役をさせる目的で作成しています。

    キャンセル

  • 2017/11/28 15:11

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

    キャンセル

  • 2017/11/28 15:14 編集

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

    キャンセル

  • 2017/11/28 15:20

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

    キャンセル

  • 2017/11/28 15:30

    !!!
    その通りです。
    ローカルループバックだけ,暗記で記述していたのが仇となりました。
    本当にどうしようもない凡ミスでした...

    実行したところ,Processing側でのBashoウィンドウでちゃんと,変数の推移が確認できました。

    umyuさん。ご指摘いただきありがとうございました。
    asahina1979さん,KSwordOfHasteさんのご指摘も,私が他にも学ぶべき情報を教えていただきました。
    重ねてお礼申し上げます。

    キャンセル

  • 2017/11/28 15:34 編集

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

    キャンセル

  • 2017/11/28 15:44

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

    キャンセル

  • 2017/11/28 15:54

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

    キャンセル

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

ただいまの回答率

91.36%

関連した質問

  • 解決済

    Unity5のテキスト表示について

    UnityでUDPデータを受信して、UIのTextに表示をしようと考えているのですが表示することができません。 言語はC#です。 11/10 Debug.Log()については表示

  • 解決済

    Webサイトのxmlコードを読み取るプログラム開発

    windows form applicationで、webサイトのxmlコードを読み込むプログラムを作りたいと考えていますが、どのように作ればよいか大まかにでも教えていただきたいと

  • 解決済

    Javaでの文字コード値取得について

    Javaでutf-8のコード値からunicodeに変換するにはどうすればいいでしょうか? public static void main(String[] args) {

  • 受付中

    Watson の speech to text を HTTP REST で呼び出す方法

    前提・実現したいこと 【IBM Watson音声認識のAPI呼び出し】 IBM Watson の HTTP REST API で speech to text の recogn

  • 解決済

    C# wave 出力方法について

    前提・実現したいこと C# kinect等の音声機器で取得した音声データを,「○○.wav」のファイルに保存したいです. 発生している問題・エラーメッセージ `

  • 解決済

    ジャグ配列をキーとしたDictionary使い方

    前提・実現したいこと ジャグ配列をキーとしたDictionaryを使用したいです 発生している問題・エラーメッセージ 「引数2を指定するメソッド、"this"のオーバーロ

  • 解決済

    MVC モデルのバリデーションについて

    モデルでアノテーション(Required)を指定しているプロパティが4つあります。 [Required] public string A { get; set;

  • 解決済

    [VB.NET]Excelのタスクの消し方

    visual studio2012 でwindowsフォームアプリを作成します。 データグリッドビューのデータをExcelに出力するようにしています。 ですが、Excelを閉じても

同じタグがついた質問を見る

  • Java

    10446questions

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

  • C#

    4754questions

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

  • Processing

    166questions

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