C++BuilderでのTServerSocketコンポーネントの使用法を、実際に動作確認用のテストプログラムを作成しながら説明します。
TServerSocketコンポーネントは、VCL用のコンポーネントですので、Windows専用のコンポーネントとなります。
尚、実際にプログラムの動作確認を行うには、TClientSocket用のテストプログラムも必要となりますので、以下の記事も参照ください。
TClientSocketの使い方、テストプログラムにつきましては、こちらの記事をご覧ください。
ソケット コンポーネントはデフォルトではインストールされません。インストール方法は以下の記事を参照してください。
TClientSocket, TServerSocketのインストールは、こちらの記事をご覧ください。
プロジェクトの作成
C++Builderで、初めてのプロジェクト作成で、説明した「SDIアプリケーション」をベースにテストプログラムを作成します。
プロジェクト名を、”server_test”に変更します。(プロジェクト名の変更を参照してください。)
次に、メッセージの表示用に、TMemoコンポーネントをDropし、Alignプロパティを”alClient”に設定します。
それから、TServerSocketコンポーネントをDropします。
最初のイベント処理を追加するを参考に、以下のイベントを追加しておきましょう。
イベント | 説明 |
---|---|
OnShow | フォームが表示されたとき(フォームの Visible プロパティが true に設定されている場合)に発生します。 |
OnCloseQuery | 問い合わせを終了しようとしたときに発生します。 |
OnClose | フォームを閉じたときに発生します。 |
TServerSocketコンポーネントのイベントの追加
TServerSocketコンポーネントの以下の4つのイベントを追加します。
イベント | 説明 |
---|---|
OnClientConnect | クライアントソケットがサーバーソケットによって受け入れられた接続を完了したときに発生します。 |
OnClientDisconnect | クライアントソケットへの接続の 1 つをクローズしたときに発生します。 |
OnClientError | 個々のクライアントソケットへのソケット接続の確立,使用,または終了で失敗が生じたときに発生します。 |
OnClientRead | サーバー ソケットがクライアント ソケットから情報を読み取らなければならないときに発生します。 |
TServerSocketコンポーネントの接続処理
TServerSocketコンポーネントに、接続を待つPort番号を設定して、Activeプロパティをtrueにします。
Open()メソッドを実行しても良いですね。Open()メソッドを実行すると、Activeプロパティはtrueとなります。
このコードは、コンストラクタか、OnShowイベントで実行すれば良いでしょう。
__fastcall TSDIAppForm::TSDIAppForm(TComponent *AOwner)
: TForm(AOwner)
{
ServerSocket1->Port = 2000;
ServerSocket1->Active = true;
}
TServerSocketコンポーネントのイベント内での処理
テストアプリケーションのTClientSocketコンポーネントのイベント内での処理を以下に示します。
OnClientConnectイベント
接続が完了した時に、Memo1にメッセージを表示しています。
void __fastcall TSDIAppForm::ServerSocket1ClientConnect(TObject *Sender, TCustomWinSocket *Socket)
{
Memo1->Lines->Add("ServerSocket1ClientConnect");
}
OnClientDisconnectイベント
接続が切れた時に、Memo1にメッセージを表示しています。
void __fastcall TSDIAppForm::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket)
{
Memo1->Lines->Add("ServerSocket1ClientDisconnect");
}
OnErrorイベント
エラーが発生したときの処理の例です。
void __fastcall TSDIAppForm::ServerSocket1ClientError(TObject *Sender, TCustomWinSocket *Socket,
TErrorEvent ErrorEvent, int &ErrorCode)
{
Socket->Close();
ErrorCode =0;
}
OnClientReadイベント
クライアント側からの送信データを受信し、Memo1に表示しています。
クライアントの接続数は、考慮していません。
ReceiveLength()で、送られて来たデータ長を取得し、ReceiveBuf()で実際にデータを受信します。
サーバーからのデータは、1バイトの文字データを想定してます。
実際には、もう少し複雑な処理になると思います。
void __fastcall TSDIAppForm::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
char buf[1024];
int Size = Socket->ReceiveLength();
if(Size > 1024) Size = 1024;
Socket->ReceiveBuf(buf, Size);
// 受信データが、ASCIIコードの文字の場合
String wstr = "";
for(int i=0;i<Size;i++)
{
wstr += buf[i];
}
Memo1->Lines->Add(buf);
}
データの送信
簡単に実装するために、ファイルの作成イベント(FileNew1)に、データ送信の処理を追加しました。
データの送信は、Socket->SendBuf()関数を使用します。
ここでも、クライアントの接続数は、考慮していません。
void __fastcall TSDIAppForm::FileNew1Execute(TObject *Sender)
{
char str[] = "Server Test";
int num = ServerSocket1->Socket->ActiveConnections -1;
ServerSocket1->Socket->Connections[num]->SendBuf(str, sizeof(str));
}
再接続処理
サーバー側は、接続を待っているだけなので、特に再接続の処理は不要です。
参考URL
Indy TIdTCPClient、Indy TIdTCPServerの使い方につきましては、以下の記事をご覧ください。
以下のHPも、参考にしてください。