web-dev-qa-db-ja.com

バイナリデータ転送のデータ形式

オシロスコープを作らなければなりません。理想的には、オシロスコープはプローブに接続します。このプローブは別のプログラムである必要があり、ローカルまたはネットワークからデータを取得できます。このデータは、数値、浮動小数点数、整数です。チャンネル数は異なる場合があります。そして、それらは時間とともに変化します。すべてのチャネルが同じ周波数である必要はありません。

現在、周波数が1KHzの場合があるため、テキストに基づいているため、jsonを使用しても問題はありません。バイナリデータ形式を探しているので、データ転送が高速です。

質問の最初の部分は、次のとおりです。このようなバイナリデータを転送する形式を知っていますか?それはある種のヘッダーを持つべきで、それから数字だけが必要です。私の推測では、誰かが以前にこの問題を抱えていたはずであり、これを使用するための何らかのライブラリがあるはずです。

次に、質問の2番目の部分が続きます。データを転送するためにどのプロトコルを使用する必要がありますか?

多分jsonを使用しますが、標準のhttp呼び出しを使用するデータにbase 64エンコーダーを使用できますが、1KHz信号の場合は意味がありません。これを解決するために人々は何をしているのだろう。

4
cauchy

「ber tlv」の件名を調べることも検討してください。

http://en.wikipedia.org/wiki/Type-length-value

これは、世界の金融処理ネットワークで使用されているデータストリーム形式であり、チップ&ピンターミナル、ATM、および他の多くの銀行システムのバックボーンです。

それについての最もよい部分は、それが使用するのが非常に簡単であることです。

T、L、Vの部分は

  • [〜#〜] t [〜#〜]ag
  • [〜#〜] l [〜#〜]長さ
  • [〜#〜] v [〜#〜]alue

Tagは、メッセージのタイプを指定する数値識別子です。この場合、フォーマットを使用するだけの場合は、独自のメッセージを定義できます。このためのタグですが、実際の財務データを実際に処理する場合は、標準で定義されているタグ番号を使用する必要があります。

Lengthの部分も簡単で、値の部分が何バイトのデータであるかを指定します。値と同様に、長さに割り当てるバイト数が多いほど、ペイロードを長くすることができます。

Valueの部分は実際のメッセージの単なるペイロードであり、バイトのフォーマット方法は完全にあなた次第です。

プロトコルのデコード/エンコードが非常に簡単であるため(バイト配列を使用して完全に行うことができます)、非常に小さく非常に高速なパケットサイズを使用して、UDP経由で簡単に送信できます。

これはストリーミングにも適しており、複数のメッセージを連続した非クローズ接続で連続して送信できます。これは、TCPを使用する必要がある場合に非常に理想的です。

理論的には、HTTP上でもWebソケットを使用してうまく機能しますが、実際に試したことがないので、コメントはできませんでした。

それをサポートしているライブラリーは、前回「クレイグズユーティリティライブラリー」を見た

https://github.com/JaCraig/Craig-s-Utility-Library

そこに浮かんでいる多くのスマートカードライブラリがそうであるように、TLVベースの構造を非常によくサポートしていました(TLVは多くのカードでも使用されています)

TLVがあなたのものではない場合、私は他の人が言ったことを間違いなくバックアップし、「Protobuf」をよく調べます

更新

私はあなたがどの言語で働いているのか、あるいは私が投稿しようとしているものがあなたにとってどんな役に立つものになるのかもわかりませんが:-)、とにかくここに行きます。

これはTLVデコーダーです(エンコード機能はありませんが、簡単に元に戻すことができます)C#を使用して2008年に書き戻しましたが、デコード用に設計されました支払端末のスマートカードから送信されるber-tlvパケットですが、それをハッキングしてより便利な形にするための出発点として役立つ場合があります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Card_Analyzer
{
  public class tlv
  {
    public int tag = 0;
    public int length = 0;
    public byte tagClass = 0;
    public byte constructed = 0;
    public List<byte> data = new List<byte>();
  }

  public class tlvparser
  {
    // List of found TLV structures
    public List<tlv> tlvList = new List<tlv>();

    // Constructor
    public tlvparser(byte[] data)
    {
      if (data != null)
      {
        this.doParse(data);
      }
    }

    // Main parsing function
    public void  doParse(byte[] data)
    {
      int fulltag = 0;
      int tlvlen = 0;
      int dptr = 0;

      while (dptr < data.Length)
      {
        byte temp = data[dptr];
        int iclass = temp & 0xC0;
        int dobj = temp & 0x20;
        int tag = temp & 0x1F;

        if (tag >= 31) // Using extracted vars, decide if tag is a 2 byte tag
        {
          fulltag = (temp << 8) + data[dptr + 1];
          tlvlen = data[dptr + 2];
          dptr += 3;
        }
        else
        {
          fulltag = temp;
          tlvlen = data[dptr + 1];
          dptr += 2;
        }// End if tag 16 bit

        if ((tlvlen & 128) == 128)
        {
          tlvlen = (tlvlen << 8) + data[dptr];
          dptr++;
        }

        tlv myTlv = new tlv();
        myTlv.tag = fulltag;
        myTlv.length = tlvlen;
        myTlv.tagClass = Convert.ToByte(iclass >> 6);
        myTlv.constructed = Convert.ToByte(dobj >> 5);

        for (int i = 0; i < tlvlen; i++)
        {
          if(dptr < data.Length)
            myTlv.data.Add(data[dptr++]);
        }

        if (myTlv.constructed == 1)
          this.doParse(myTlv.data.ToArray());

        tlvList.Add(myTlv);

      }// End main while loop
    }// End constructor
  }// end class tlvparser
}// end namespace

役に立たない場合は、無視してかまいません。

5
shawty

[〜#〜] edf [〜#〜] と呼ばれるファイル形式があり、マルチチャネル、マルチサンプルレートデータのストリームをシリアル化することを目的としています。ファイル構造は、ネットワークストリームやプローブとオシロスコープの間の他のバイトストリームと同じようにストリームであるため、例として使用すると適切です。

EDF形式のアイデアは、さまざまなデータチャネルをデータ「ブロック」に多重化することです。各ブロックには、各チャネルからの所定の時間が含まれ、ブロックはファイルにシリアルに保存されます。

ファイル自体には、ファイルとチャネルに関する情報を含むファイルヘッダーが含まれ、次に各チャネルに関する情報を含むNチャネルヘッダーが含まれ、その後生のみデータ。したがって、仮にヘッダーデータを失うと、信号を(少なくとも簡単に)再構成できなくなります。

最後に、このファイル形式の数値部分(生データ)は固定されているため単純です。すべての値の型はInt16(短整数、2バイト、リトルエンディアン)です。

次に、このファイル形式がネットワーク転送のコンテキストでどのように役立つかを見てみましょう。

  • ネットワーク転送は、セッションがあり、このセッションが構成されている(つまり、送信者と受信者の間の契約がある)ことを前提としており、セッション構成は予期せず変更されません。これは、プローブから情報を取得できる(または逆に設定できる)ことを意味します。この構成情報は、受信者が各データフレームの構造を知るのに十分なはずです。したがって、2つの瞬間があります。1つはデータ転送(プローブとオシロスコープの間で「ヘッダー」データを送信する)を構成し、もう1つはデータ転送自体(特定の形式でデータフレームをシリアル送信する)です。

  • データフレームの場合、これは(通常どおり)指定された長さのバイトストリーム/配列であり、情報をエンコードする必要があります。通常、 Type-Length-Value のようなものを使用します。ここで、「Type」は「何が来るか」を表す事前定義された長さのフィールド、「Length」は次のバイト数を表す別のフィールドです長さフィールドには、最終的に「値」自体がデータ自体があります。

あなたの質問から、設定可能な変数は次のようです:

  • チャネルの数。
  • 特定のチャネルのサンプリングレート。
  • 数値タイプ:int、float、double;

「バイナリ」形式の意味がよくわかりませんでしたが、これをテキスト(ASCII、UTFなど)と比較すると思います。すべてのストリームベースの転送はシーケンシャルbytesで構成されることに注意してください。数値をバイトの配列(floatは4バイト、doubleは8バイト、Uint16(別名short)は2バイトなどです)。また、すべての言語には、メモリ内の型付き数値とストリーム内のバイトとの間で変換するためのライブラリがあります。

これがお役に立てば幸いです。必要に応じてコメントしてください。私は現在、現在のプロジェクトでマルチチャネルデータ取得用のカスタムバイナリファイル形式を正確に使用しており、確かにそれについていくつかの意見を交換できました。

2
heltonbiker

Base 64エンコーディングは、テキストチャネルを介してバイナリデータを送信するために使用されます。それはあなたが望むものの正反対です。それは単にコードのエンコード/デコードを必要とし、メッセージを大きくします。

送信する必要のあるデータを正確に知らなければ、推奨を行うことは困難です。コンパクトになるように設計されているため、 Protocol Buffers を確認することをお勧めします。

1
Gort the Robot