0

まず、私はsockectsとTCP / IPパケットを使用したネットワークに非常に慣れていないので、非常に明確な方法で説明していただければ幸いです。私のロボティクスプログラムは、現在のロボットで初めてkinectを使用しようとしていますが、問題があります。現在、Javaでコーディングしていますが、KinectをC++でコーディングする予定です。TCP / IPパケットを使用して2つの言語間で情報を送信することは可能ですか?C++クライアントとJavaサーバーが必要です。誰かがリンクや例を持っているなら、私は本当にそれを感謝します、ありがとう!

4

3 に答える 3

1

JavaとC/C ++の間で通信する実際の問題は、バイト順序の問題です。バイナリデータを送信する場合は、通信構造を明確かつ完全に設計する必要があります。これには、数値サイズ(バイト単位)、ビット順序(lsb / msb、スワップバイトまたは非スワップバイトの略、int、およびlongs)、および構造体パッキング(構造体のフィールド間のパッドバイト数)。

回避できる場合は、バイナリで通信しないことをお勧めします。2つの理由で;

  1. ビット順序、バイトスワッピング、および構造体のパッキングについて心配する必要はありません。
  2. データをデコードせずに通信を盗聴します。ここにはまだASCII/Unicodeの問題があります。

編集 C/C ++では、データはCPUアクセスを高速かつ簡単にする方法で保存されます。クラス/構造のフィールドはワード境界に配置され(ほとんどのCPUはフルワードチャンクのメモリにしかアクセスできないため)、ビットはCPUと一致するように順序付けられます。ただし、CPUのビット順序とワードサイズは異なる場合があります(16、32、64、...)。ほとんどのIntelCPUはリトルエンディアンであり、他のほとんどのデザインはビッグエンディアンです。人生をより面白くするために、Java仮想マシンはすべてのプラットフォームでビッグエンディアンです。http://en.wikipedia.org/wiki/Endianness

したがって、2台のC / C ++マシンが通信できるようにする場合は、両方がデータを読み取れる方法でデータを送信する必要があります。通常、異種環境(「ネットワーク経由」と呼ばれる)で通信するには、すべての通信が特定の形式で行われるように指定します。TCP / IPは、MSB(最上位ビット)の順序を使用します。次に、すべてのプログラムは、(必要に応じて)ワイヤー形式から変換する必要があります。

CPUはワード長のチャンクでメモリを消費するため、コンパイラは、マシンワード全体を埋めないフィールドの間にパッドバイトを配置します。32ビットワードを読み取るマシンの場合、次のような構造になります。

struct example1 {
  char someFlag;
  int  someCount;
};

実際には8バイトのメモリが必要になります。最初のフィールドは1バイトのデータと3つのパッドバイトで構成されているため、整数参照はワード境界に配置されます。ナイーブなコミュニケーターがこの構造のデータを送信しようとした場合、たとえば、send(&example1, sizeof(example1));ワードサイズやバイト順序が異なる別のシステムに送信しようとするとread(&example1, sizeof(example1));、example1.someCountの値は予想とは大きく異なる可能性があります。

これのほとんどは、Javaを投入するまでは通常アカデミックです。Javaは常にMSB形式だからです。したがって、同じハードウェア上であっても、C / C ++アプリケーションからJavaアプリケーションに送信すると、これと同じ予期しない結果が生じる可能性があります。

Javaには、私のお気に入りのI/Oクラスが含まれていますjava.nio.ByteBuffer。事実上すべてのソースからint、long、float、およびdoubleを読み取る機能があります。データがどのように作成されたかを知っている場合、これはそれを読み取ります。ByteBufferにはgetShortgetInt任意の型を取得するための、などのメソッドとorder()、データのバイト順序を設定するためのメソッドがあります。

于 2012-10-10T18:46:28.180 に答える
1

2つのプログラムがネットワークを介して相互に通信する必要がある場合は常に、プロトコルを定義する必要があります。

TCP上で定義されたプロトコルは、メッセージ全体が受信されたことを受信者に通知する方法を指定する必要があります。これを行う2つの一般的な方法は次のとおりです。

  • 「終了」を通知するデータの特別なシーケンスを指定します。例として、メッセージの非ペイロード部分の終了を通知するために特別なCRLF文字を使用するHTTPがあります。
  • メッセージの事前定義された部分でメッセージの長さを指定します。例として、「Content-Length」ヘッダーでペイロードの長さを指定するHTTPがあります。

HTTPメッセージ構造の詳細については、http ://www.w3.org/Protocols/rfc2616/rfc2616-sec4.htmlを参照してください。

さらに、ペイロードをエンコードするためのプラットフォームに依存しない形式が必要になる可能性があります。優れたバイナリ形式は、JavaおよびC ++で非常によくサポートされているGoogleのプロトコルバッファです:http ://code.google.com/p/protobuf/

于 2012-10-10T21:40:41.667 に答える
0

もちろん、異なる言語で実装されたプログラム間で情報を交換することもできます。(インターネット全体がJavaを使用することを期待していましたか?)

これがグーグルの「ソケットプログラミング{Java、C++}」の後で見つけたものです。

http://codebase.eu/tutorial/linux-socket-programming-c/-問題ないようです

http://www.javaworld.com/jw-12-1996/jw-12-sockets.html-Javaチュートリアル

ただし、注意してください。ハードウェアアーキテクチャによっては、バイナリデータを交換するときに問題が発生する場合があります(バイト順序など)。オブジェクト指向言語を使用しているので、低レベルの通信を処理するある種のミドルウェア(Iceなど)の使用を検討できます。ただし、これはあなたの場合はやり過ぎかもしれません。

于 2012-10-10T18:10:31.513 に答える