2015-05-08 c++ builder XE4 > tcpサーバ / tcpクライアント

```txt:動作確認
C++ Builder XE4
```

同じPC内でTCP通信する例。

B_serverボタンをクリックしてからB_clientボタンをクリックして動かす。

WriteLn()のところをWrite()としてしまい、処理が終わらずにはまった。このあたりもう少し勉強が必要。


#案1

B_clientClick時のWriteLn()の後にSleepしないと複数回の処理に失敗する点は勉強が必要。


```sample.cpp
//---------------------------------------------------------------------------
void __fastcall TForm1::B_serverClick(TObject *Sender)
{
	IdTCPServer1->DefaultPort = 55555;
	IdTCPServer1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
	UTF8String rcvdStr;

	rcvdStr = AContext->Connection->IOHandler->ReadLn(
		IndyTextEncoding(TEncoding::UTF8) );

	TList *threads;
	TIdContext *ac;

	threads = IdTCPServer1->Contexts->LockList();

	ac = reinterpret_cast<TIdContext *>(threads->Items[0]);

	UTF8String sendStr;
	sendStr = "send:" + rcvdStr;

	ac->Connection->IOHandler->WriteLn(sendStr);

	for(int idx=0; idx<10; idx++) {
		Sleep(100);
		Application->ProcessMessages();
	}
	ac->Connection->Disconnect();

	IdTCPServer1->Contexts->UnlockList();
}
//---------------------------------------------------------------------------

static int num=1;
void __fastcall TForm1::B_clientClick(TObject *Sender)
{
	IdTCPClient1->Host = L"127.0.0.1";
	IdTCPClient1->Port = 55555;

	IdTCPClient1->Connect();

	IdTCPClient1->IOHandler->WriteLn(L"test");
	for(int idx=0; idx<10; idx++) {
		Sleep(100);
		Application->ProcessMessages();
	}

	//TBytes Buffer;
	String buffer;
	while(1) {
		if (IdTCPClient1->IOHandler->InputBufferIsEmpty() == false) {
			Application->ProcessMessages();
			Sleep(100);
			continue;
		}
		if (IdTCPClient1->IOHandler->CheckForDataOnSource(100) == false) {
			break;
		}

		int size = IdTCPClient1->IOHandler->InputBuffer->Size;

		//IdTCPClient1->IOHandler->ReadBytes(Buffer, size, /* AApend=*/ false);

		buffer = IdTCPClient1->IOHandler->ReadLn();

		int nop=1;

		buffer = buffer + L":" + IntToStr(num++);
		Memo1->Lines->Add(buffer);
	}

	IdTCPClient1->IOHandler->InputBuffer->Clear();

	IdTCPClient1->Disconnect();
}
//---------------------------------------------------------------------------
```

#改良案2
こちらの方ではB_clientClick()でSleep()を使わなくてよさそう。

```cpp
//---------------------------------------------------------------------------
void __fastcall TForm1::B_serverClick(TObject *Sender)
{
	IdTCPServer1->DefaultPort = 55555;
	IdTCPServer1->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
	UTF8String rcvdStr;

	rcvdStr = AContext->Connection->IOHandler->ReadLn(
		IndyTextEncoding(TEncoding::UTF8) );

	TList *threads;
	TIdContext *ac;

	threads = IdTCPServer1->Contexts->LockList();

	ac = reinterpret_cast<TIdContext *>(threads->Items[0]);

	UTF8String sendStr;
	sendStr = "send:" + rcvdStr;

	ac->Connection->IOHandler->WriteLn(sendStr);

	for(int idx=0; idx<10; idx++) {
		Sleep(100);
		Application->ProcessMessages();
	}
	ac->Connection->Disconnect();

	IdTCPServer1->Contexts->UnlockList();
}
//---------------------------------------------------------------------------

static int num=1;
void __fastcall TForm1::B_clientClick(TObject *Sender)
{
	IdTCPClient1->Host = L"127.0.0.1";
	IdTCPClient1->Port = 55555;

	IdTCPClient1->Connect();

	IdTCPClient1->IOHandler->WriteLn(L"test");
	if (IdTCPClient1->IOHandler->CheckForDataOnSource(1000)) {
		String buffer;
		buffer = IdTCPClient1->IOHandler->ReadLn();
		buffer = buffer + L":" + IntToStr(num++);
		Memo1->Lines->Add(buffer);
		int nop=1;
	}
	IdTCPClient1->IOHandler->InputBuffer->Clear();

	IdTCPClient1->Disconnect();
}
//---------------------------------------------------------------------------
```