5

どこでも検索してみましたが、うまくいきませんでした。これが私の問題です:

私はUDPソケットを持っています。これは、任意のポートを介して任意のIPアドレスにデータを送信できます(動作がテストおよび確認されています)。

私は多くのチュートリアルを読みましたが、それらはすべて操作char*[]していて、それを復号化する方法を指定していませんでした。

私がやりたいこと(擬似コード):

クライアント:

Class my_class;
send (..., my_class, sizeof(my_class),...)

サーバ:

receive (sender, buffer, sizeof (buffer))
and do something like
Class my_class = (Class) buffer

だから私は私のサーバーがバッファの内容を分析することができます。

しかし、私はポインタに迷い、送信できるのはchar*[]、だけなので、前後に変換する方法がわかりません。

4

2 に答える 2

6

クラスを「送信」することはできません。クラス内のデータの表現を送信する必要があります。また、クラスへのポインターの送信も機能しません。ネットワーク上の別のアプリケーションがあなたのポインターを受け取った場合、それは彼らにとって無意味になります。

このことを考慮:

class Data
{
  std::string  name_;
  unsigned value_;
} data;

単純に「クラスを送信」することはできません。このようなことをしようとした場合:

send(&data, sizeof(data));

...下流のクライアントにナンセンスを送信することになります。 value_適切に受信される可能性がありますが、name_確実に受信されません。これは、std::stringオブジェクトが文字列を構成する文字だけで構成されているためです。また、カウンター、データ バッファーへのポインター、および他に何を知っている人もいます。文字自体は、おそらく で示されるメモリ空間には存在し(&data, &data[sizeof(data)])ません。これらの文字は、完全に別の場所にあります。したがって、send上記の psudocude では、クライアントが理解できないものを大量に送信するだけでなく、クライアントが理解できるものを送信しないこともよくあります

シリアライゼーションを入力します。シリアライゼーションとは、どこかに保存、保存、または送信し、後で再構築できるデータ オブジェクトの表現を作成することを意味します。この連載の形を決めるのはあなたです。上記の場合、次のdataようにシリアル化することを決定できます。

NNNNCCCCCCCC...VVVV

ここで、各文字は 1 バイトで、次のとおりです。

  1. name_N は 4 文字の整数で、ASCII 表現の文字数です。
  2. C は N バイトで、それぞれが 1 文字です。name_
  3. V は 4 文字の符号なし整数でvalue_、ASCII 表現の値です。

上記をシリアル化して送信する 1 つの方法dataは、次のようなものです (警告: 製品品質ではなく、テストされていません):

stringstream ss;
ss 
  << setw(4) << setfill('0') << right << data.name_.length() << setw(0)
  << data.name_
  << setw(4) << data.value_;

  string buf = ss.str();

  send(buf.c_str(), buf.length());

を送信しようとする代わりにdata、 を表す文字列を送信していますdata。が次のように作成された場合data:

data.name_ = "foo";
data.value_ = 42;

...その後、ソケットに送信される文字列は次のようになります。

0003foo0042

これはクライアントによって受信されData、サーバー側にあるものを模倣するクライアント側の新しいオブジェクトに再構築されます。

上で使用したマッピング -- the NNNNCCCCCCCC...VVVV-- は、両側で理解する必要があります。これは、通信プロトコルと呼ばれることがよくあります。

すべてのアプリケーション ドメインで使用される無数のプロトコルとシリアル化方法があります。それらは、上で概説したような非常に単純なものから、FIX/FASTのような高度に圧縮された複雑なものまでさまざまです。多くのライブラリは、幅広いアプリケーションのニーズを満たすシリアル化機能を提供します。 Boost.Serializationが頭に浮かぶので、調べてみることをお勧めします。

これには、ここで説明したこと以外にも多くのことがあります。エンディアン、セキュリティ、セッション制御など... クライアント側またはサーバー側のいずれかで重要なネットワーク プログラミングを行う場合は、事前にかなりの学習が必要です

于 2012-05-04T15:06:33.727 に答える
1

クラスをシリアル化する必要があります。char*[]これはバイナリ表現に変換され、データ型の中に入れて送信できます。char * []は実際には送信するバイトを保持しているだけなので、クラスをバイトに変換する必要があります。反対側に到着したら、逆シリアル化する必要があります。つまり、バイトの配列からオブジェクトに変換し直します。

于 2012-05-04T14:34:53.957 に答える