クラス: wxServer, wxConnection, wxClient
wxWidgets にはプロセス間通信やネットワークプログラミングを支援する様々なクラスがあります。この章では DDE 風のプロトコルを使用するひとつのクラス群についてのみ説明しますが、その代わりに他の有用なクラスの一覧を以下に示します:
wxWidgets の DDE 風プロトコルは Windows DDE に基づく高レベルのプロトコルです。このDDE 風プロトコルには 2 種類の実装があります: ひとつは実際の DDE を使用する方法で、WIndows のみで実行できます。もうひとつは TCP/IP (ソケット) を使用する方法で、ほとんどのプラットフォームで実行できます。クラス名を除いて API と仮想的な振る舞いがすべて同じであるため、ふたつの実装を簡単に切り替えられることに気がつくと思います。
<wx/ipc.h>
をインクルードすることで IPC クラス用の便利なシノニムを定義できます: DDE ベースの実装とソケットベースの実装のどちらを使用するかによって wxDDEServer もしくは wxTCPServer のいずれかが wxServer として定義されます。同様のことが wxClient と wxConnection に対しても行われます。
Windows ではデフォルトで DDE 版が使用されます。DDE は同じコンピュータ内でのみ動作します。もし異なるワークステーション間で IPC を使用したい場合、このヘッダファイルをインクルードする前に wxUSE_DDE_FOR_IPC
を 0 に定義してください。これにより、Windows でも強制的に TCP/IP 版が使用されるようになります。
以降の説明では wxWidgets について言及しますが、同じ wxTCP* クラスと wxDDE* クラスは同様の方法で使用できることを覚えておいてください。
DDE 風 API では中心となるクラスが 3 種類あります:
通常、アプリケーション間のメッセージは 3 種類の変数で識別されます: コネクションオブジェクト、トピック名、アイテム名です。いくつかのメッセージではデータ文字列が 4 番目の要素になります。コネクション (Windows で言うところの会話 (conversation)) を作成するにはクライアントアプリケーションでサービス名 (サーバを識別します) とトピック名 (接続している間のトピックを識別します) を指定して wxClient::MakeConnection を呼び出します。Unix におけるサービス名はインターネットドメインソケットが通信に使用する整数のポート識別子か、Unix ドメインソケットが作成する有効なファイル名 (このファイルは存在してはならず、後で削除されます) のいずれかになります。
セキュリティ上の注意: インターネットドメインソケットを使用したプロセス間通信は非常に危険です。なぜなら、これらの通信に対するアクセス制御はまったく行われないためです。可能な限り、Unix ドメインソケットを使用してください。
そして、サーバが応答し、接続を拒否または許可します。接続が許可されるとサーバとクライアントの双方で wxConnection が作成され、接続が閉じられるまで維持されます。作成されたコネクションオブジェクトはクライアント・サーバ間でのメッセージの送受信に使用されます。このとき、wxConnection を継承したクラスで仮想関数をオーバーライドすると DDE メッセージを処理することができます。
動作するサーバを作成するには次のようにする必要があります:
動作するクライアントを作成するには次のようにする必要があります:
他のアプリケーションへデータを転送するにはいくつかの方法があります。これらは wxConnection の関数です。
デフォルトのデータ型は wxCF_TEXT (ASCII テキスト) で、デフォルトのデータサイズはヌル終端文字列の文字列長です。また、Windows 独自のデータ型を使用することもできます。
IPC サンプルディレクトリにある server と client のサンプルプログラムを参照してください。サーバを実行し、それからクライアントを実行してください。このサンプルでは Advise ループとともに Execute、Request、Poke コマンドを使用しています: サーバ側のリストボックスを選択すると、選択された項目がクライアント側のリストボックスでハイライトされます。
wxClient オブジェクトは DDE 風 (Dynamic Data Exchange) 通信のクライアント・サーバ通信のクライアント部分を初期化します。(Windows と Unix の両方で利用可能です)
適切なサーバと通信するクライアントを作成するには wxConnection と wxClient をそれぞれ継承する必要があります。wxConnection の継承クラスはサーバとの '会話' (conversation) におけるやり取りを受信します。そして wxServer を継承したクラスが必要になります。これにより、接続が確立したときに wxClient::OnMakeConnection をオーバーライドした関数が要求されたクラスの wxConnection を返却できるようになります。
以下に例を示します:
class MyConnection: public wxConnection { public: MyConnection(void)::wxConnection() { } ~MyConnection(void) { } bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) { wxMessageBox(topic, data); } }; class MyClient: public wxClient { public: MyClient(void) { } wxConnectionBase* OnMakeConnection(void) { return new MyConnection; } };
ここでは MyConnection がサーバから送信された OnAdvise メッセージに反応してメッセージボックスを表示します。
クライアントアプリケーションを実行するときには wxClient の継承クラスのインスタンスを作成する必要があります。以下ではコマンドライン引数を使用してホスト名 (サーバを実行しているマシン名)、(サーバプロセスを識別する) サーバ名を引き渡しています。wxClient::MakeConnection を呼び出すと接続要求が受け付けられた場合に MyConnection のインスタンスが暗黙的に作成されます。そして、クライアントはサーバからの Advise ループを要求します。(Advise ループとはデータが変更されたときにサーバがクライアントを呼び出すところのことです)
wxString server = "4242"; wxString hostName; wxGetHostName(hostName); // 新しいクライアントを作成する MyClient *client = new MyClient; connection = (MyConnection *)client->MakeConnection(hostName, server, "IPC TEST"); if (!connection) { wxMessageBox("Failed to make connection to server", "Client Demo Error"); return NULL; } connection->StartAdvise("Item");