クラスを「送信」することはできません。クラス内のデータの表現を送信する必要があります。また、クラスへのポインターの送信も機能しません。ネットワーク上の別のアプリケーションがあなたのポインターを受け取った場合、それは彼らにとって無意味になります。
このことを考慮:
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 バイトで、次のとおりです。
name_
N は 4 文字の整数で、ASCII 表現の文字数です。
- C は N バイトで、それぞれが 1 文字です。
name_
- 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が頭に浮かぶので、調べてみることをお勧めします。
これには、ここで説明したこと以外にも多くのことがあります。エンディアン、セキュリティ、セッション制御など... クライアント側またはサーバー側のいずれかで重要なネットワーク プログラミングを行う場合は、事前にかなりの学習が必要です。