Невозможно отправить текст с TIdTCPServer На TIdTCPClient , сервер завис (не отвечает), он просто зависает при попытке отправить текст клиенту.
IНачато недавно с использованием Indy TIdTCPClient и TIdTCPServer, у меня клиентское приложение работает хорошо при отправке и получении ответа от серверной формы, затем проблема с сервера, он не отправляет данные, и когда я пытаюсь отправить данные, как создатели Indy, предоставленные вих Doc, он просто зависает, а затем перестает отвечать (вылетает) :(, странно то, что сервер отправляет ответ на событие Execute, а не отправляет данные с моей функцией отправки, поэтому вот мой код, который я использую:
Событие выполнения сервера:
void __fastcall TServerMain::IdTCPServer1Execute(TIdContext *AContext)
{
UnicodeString uMessage;
uMessage = AContext->Connection->IOHandler->ReadLn();
MessageDisplay1->Lines->Add(uMessage);
AContext->Connection->IOHandler->WriteLn("Response OK!"); // i can receive the response from the client
}
Функция отправки на сервер:
void TServerMain::itsSendMessage(TIdTCPServer *itsName, UnicodeString uMessage) {
TIdContextList *Clients;
TIdContext *icContext;
if ( uMessage.Length() != 0 && itsName->Active ) {
Clients = itsName->Contexts->LockList();
for (int i = 0; i < Clients->Count; i++) {
icContext = (TIdContext*)Clients->Items[i];
icContext->Connection->IOHandler->WriteLn(uMessage);
}
itsName->Contexts->UnlockList();
}
} // this function doesn't send text to the clients however, it just hangs the application for ever.
Дополнительное примечание: Сервер TIdTCPServer прекращает отправкутекст даже из события OnExecute
, когда клиент отключен!
ОБНОВЛЕНИЕ:
void __fastcall TMyContext::AddToQueue(TStream *AStream)
{
TStringList *queue = this->FQueue->Lock();
try {
queue->AddObject("", AStream);
this->FMessageInQueue = true;
}
__finally
{
this->FQueue->Unlock();
}
}
void __fastcall TMyContext::CheckQueue()
{
if ( !this->FMessageInQueue )
return;
std::unique_ptr<TStringList> temp(new TStringList);
TStringList *queue = this->FQueue->Lock();
try {
temp->OwnsObjects = true;
temp->Assign(queue);
queue->Clear();
this->FMessageInQueue = false;
}
__finally
{
this->FQueue->Unlock();
}
for (int i = 0; i < temp->Count; i++) {
this->Connection->IOHandler->Write( static_cast<TStream*>(temp->Objects[i]), static_cast<TStream*>(temp->Objects[i])->Size, true );
}
}
Функция отправки на сервер:
void __fastcall TServerMain::IdSendMessage(TIdTCPServer *IdTCPServer, TStream *AStream)
{
if ( !IdTCPServer->Active )
return;
TIdContextList *Clients = IdTCPServer->Contexts->LockList();
try {
for (int i = 0; i < Clients->Count; i++) {
static_cast<TMyContext*>(static_cast<TIdContext*>(Clients->Items[i]))->AddToQueue(AStream);
}
}
__finally
{
IdTCPServer->Contexts->UnlockList();
}
}
Функция приема клиента:
void __fastcall TReadingThread::Receive() {
TMemoryStream * ms = new TMemoryStream();
this->IdTCPClient1->IOHandler->ReadStream(ms);
ms->Position = 0;
ClientMain->Image1->Picture->Bitmap->LoadFromStream(ms);
delete ms;
}
Эта функция Synchronized
в TThread
.
Вот как я отправляю a TBitmap
с использованием TMemoryStream
:
void __fastcall TServerMain::CaptureDesktop()
{
// Capture Desktop Canvas
HDC hdcDesktop;
TBitmap *bmpCapture = new TBitmap();
TMemoryStream *Stream = new TMemoryStream();
try {
bmpCapture->Width = Screen->Width;
bmpCapture->Height = Screen->Height;
hdcDesktop = GetDC(GetDesktopWindow());
BitBlt(bmpCapture->Canvas->Handle, 0,0,Screen->Width, Screen->Height, hdcDesktop, 0,0, SRCCOPY);
bmpCapture->SaveToStream(Stream);
Stream->Position = 0;
IdSendMessage(IdTCPServer1, Stream);
}
__finally
{
ReleaseDC(GetDesktopWindow(), hdcDesktop);
delete bmpCapture;
delete Stream;
}
}