動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
1対1通信の動作確認
関連
c++ builder XE4 > tcpサーバ / tcpクライアント
にて実装済みではあった。
単純なecho serverとしての実装について整理しておく。
確認手順
NonSoftさんのTCP/IPテストツールをクライアントとして使わせていただきます。
以下を行った。
- 接続する
- TEXT送信 (
hello<CR><LF>
) - 2を繰返す
- 切断する
- 1に戻る
1対1通信
参考: ソケットライブラリのIndyを利用したクリップボード共有ソフト
コマンドを送信したクライアントに対してecho backする実装。
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
IdTCPServer1->DefaultPort = 7000;
IdTCPServer1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
AnsiString rcvdStr;
// <LF>終端受信
rcvdStr = AContext->Connection->IOHandler->ReadLn(IndyTextEncoding(932));
AContext->Connection->IOHandler->WriteLn(rcvdStr);
}
//---------------------------------------------------------------------------
過去の実装ではIdTCPServer1Execute()においてApplication->ProcessMessages();
とSleepを実施していたが、不要であるように思う。
1対N通信
一つのクライアントからコマンドを受けた時、接続中の全クライアントに応答文字列を返す実装。
LockListを使う。
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
IdTCPServer1->DefaultPort = 7000;
IdTCPServer1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
AnsiString rcvdStr;
// <LF>終端受信
rcvdStr = AContext->Connection->IOHandler->ReadLn(IndyTextEncoding(932));
TList *threads;
TIdContext *ac;
threads = IdTCPServer1->Contexts->LockList();
for(int idx=0; idx < threads->Count; idx++) {
ac = reinterpret_cast<TIdContext *>(threads->Items[idx]);
ac->Connection->IOHandler->WriteLn(rcvdStr);
}
IdTCPServer1->Contexts->UnlockList();
}
//---------------------------------------------------------------------------
クライアントそれぞれに対する応答ではないので、こういう実装は使う機会がないかもしれない。