I am using c++ builder XE8, and I am just a beginner. I don't know anything about Delphi. To listen for incoming data on server and client both end, I inserted Thread Object
from Flie->New->Other->C++ builder Files
(as I saw in a video demo of threading), and named it TSocketThreard.
On the client end I assign the client socket to a TIdIOHandlerSocket var (fsock) and used the following code to listen continuously for imcoming data. len is int, s is String var and lbox is a TListBox.
void __fastcall TSocketThread::Execute()
{
FreeOnTerminate = True;
while(1){
if (Form1->fsock != NULL && Form1->fsock->Connected()) {
if(Form1->fsock->CheckForDataOnSource(10))
Form1->len = Form1->fsock->ReadLongInt();
Form1->s = Form1->fsock->ReadString(Form1->len);
Form1->lbox->Items->Add(Form1->s);
}
}
}
I tried to start it from client's onConnect event and from a button(I use to connect the client to server) also. But both times its got freeze.
On the server end I tried to OnExecute event on the same way. I mean, at first assigned socket to a var, put the code like above on a thread's(which I inserted like before) execute method, and started the thread's start() method from onExecute event.For the server I want to make it work on asynchronous mode (to handle at least few hundreds clients).
I can feel I am doing it the wrong way, but its really hard to find a good example in c++. Please some one show me the right way.
Indy servers are already multi-threaded, you don't need to create your own reading threads. The TIdTCPServer::OnExecute
event runs in a thread, and each client has its own thread. Just use the socket that the event gives you, don't use your own variable.
void __fastcall TMyServerForm::IdTCPServer1Execute(TIdContext *AContext)
{
// use AContext->Connection->IOHandler as needed...
}
On the client side, your reading thread is doing things that are not thread-safe, which can lead to UI freezing, amongst other problems. Try something more like this instead:
class TSocketThread : public TThread
{
private:
TIdIOHandler *fIOHandler;
String fString;
void __fastcall UpdateListBox();
protected:
virtual void __fastcall Execute();
public
__fastcall TSocketThread(TIdIOHandler *AIOHandler);
};
__fastcall TSocketThread::TSocketThread(TIdIOHandler *AIOHandler)
: TThread(false), fIOHandler(AIOHandler)
{
}
void __fastcall TSocketThread::Execute()
{
while (!Terminated)
{
int len = fIOHandler->ReadLongInt();
fString = fIOHandler->ReadString(len);
Synchronize(&UpdateListBox);
}
}
void __fastcall TSocketThread::UpdateListBox()
{
Form1->lbox->Items->Add(fString);
}
TSocketThread *Thread = NULL;
void __fastcall TMyClientForm::IdTCPClient1Connected(TObject *Sender)
{
Thread = new TSocketThread(IdTCPClient1->IOHandler);
}
void __fastcall TMyClientForm::IdTCPClient1Disconnected(TObject *Sender)
{
if (!Thread) return;
Thread->Terminate();
if (!IsCurrentThread(Thread))
{
Thread->WaitFor();
delete Thread;
Thread = NULL;
}
}