Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TServerSocket thread example

275 views
Skip to first unread message

Randy Morrow

unread,
May 7, 2002, 11:19:33 AM5/7/02
to
Hi All,
Does anyone have a simple (and functional) example of a thread using
TServerSocket in blocking mode? I am trying to follow the example in the
Borland help files, with little (actually no) success. It would really help
to see an example showing the class definition, with the constructor and
simple ClientExecute code, as well as the creation in the OnGetThread event
handler. I'm not asking for much, am I? ;-) Thanks.

Randy


Remy Lebeau [TeamB]

unread,
May 7, 2002, 12:16:26 PM5/7/02
to
Hee you go:


void __fastcall TForm1::ServerSocket1GetThread(TObject* Sender,
TServerClientWinSocket* ClientSocket, TServerClientThread* &SocketThread)
{
SocketThread = new TMyThread(ClientSocket);
}


class TMyThread : public TServerClientThread
{
protected:
void __fastcall ClientExecute();
public:
__fastcall TMyThread(TServerClientWinSocket* ASocket);
};
__fastcall TMyThread::TMyThread(TServerClientWinSocket* ASocket)
: TServerClientThread(true, ASocket)
{
// do any initializations that you need

Resume();
}

void __fastcall TMyThread::ClientExecute()
{
TWinSocketStream *strm = new TWinSocketStream(ClientSocket, 5000);

while(!Terminated && (ClientSocket && ClientSocket->Connected))
{
if(!strm->WaitForData(strm->TimeOut))
continue;

if(strm->Read(some_buffer, some_size) != some_size)
break;

// process some_buffer as needed
}

delete strm;
}


Gambit

"Randy Morrow" <rmo...@protus.com> wrote in message
news:3cd7f084$1_1@dnews...

Randy Morrow

unread,
May 7, 2002, 1:55:01 PM5/7/02
to
Thanks! That is exactly what I needed. Now I begin to understand what's
going on.

Randy


"Remy Lebeau [TeamB]" <gamb...@yahoo.com> wrote in message
news:3cd7fca2$1_2@dnews...

michael

unread,
May 18, 2002, 9:22:08 AM5/18/02
to

But how can you detect, that the client has disconnected? OnClientDisconnect does not work anymore.
Have you an idea to solve the problem?

Thanks - Michael

Frank Birbacher

unread,
May 18, 2002, 2:52:28 PM5/18/02
to
Hi!

michael wrote:
>
> But how can you detect, that the client has disconnected? OnClientDisconnect does not work anymore.
> Have you an idea to solve the problem?
>

> >> while(!Terminated && (ClientSocket && ClientSocket->Connected))

Guess what? Right, ClientSocket->Connected returns false if the client
is disconnected.

Frank

Michael

unread,
May 18, 2002, 2:59:39 PM5/18/02
to

Thank you Frank, I will change the the "if condition" according to your suggestion.
Michael

Frank Birbacher

unread,
May 18, 2002, 3:12:28 PM5/18/02
to
Hi!

Michael wrote:
>
> Thank you Frank, I will change the the "if condition" according to your suggestion.
> Michael
>
> Frank Birbacher <bloodym...@gmx.net> wrote:
> >Hi!
> >
> >michael wrote:
> >>
> >> But how can you detect, that the client has disconnected? OnClientDisconnect does not work anymore.
> >> Have you an idea to solve the problem?
> >>
> >> >> while(!Terminated && (ClientSocket && ClientSocket->Connected))

Where is the need for a change?

Frank

Remy Lebeau [TeamB]

unread,
May 18, 2002, 4:19:41 PM5/18/02
to
I already shows you how to do exactly that in my previous reply:

while(!Terminated && (ClientSocket && ClientSocket->Connected))
{
if(!strm->WaitForData(strm->TimeOut))
continue;

if(strm->Read(some_buffer, some_size) != some_size)
break;

// process some_buffer as needed
}

ClientSocket->Connected is true while the client is conected. When
Connected becomes false, the client has disconnected and the thread ends.
In the event that Connected is not updated correctly upon disconnection (a
known issue), then WaitForData() happens to return true even though there's
no awaiting data, and Read() fails, thus breaking the loop so the thread can
still end correctly.


Gambit

"michael" <gr...@dhzb.de> wrote in message news:3ce65580$1_1@dnews...

michael

unread,
May 18, 2002, 6:16:44 PM5/18/02
to

Frank Birbacher <bloodym...@gmx.net> wrote:
>Hi!
>
>Michael wrote:
>>
>> Thank you Frank, I will change the the "if condition" according to your suggestion.
>> Michael
>>
>> Frank Birbacher <bloodym...@gmx.net> wrote:
>> >Hi!
>> >
>> >michael wrote:
>> >>
>> >> But how can you detect, that the client has disconnected? OnClientDisconnect does not work anymore.
>> >> Have you an idea to solve the problem?
>> >>
>> >> >> while(!Terminated && (ClientSocket && ClientSocket->Connected))
>
>Where is the need for a change?
>
>Frank

Well, my if-condition was:
while(!Terminated && ClientSocket->Connected). When I change the code there is still no difference:
When the client disconnects and I set a breakpoint to the "if condition line" then ClientSocket->Connected is still "true"
and the thread is still active. I can't figure out where the problem is.
Thank you for you help, anyways!
Michael


Michael

unread,
May 18, 2002, 6:24:27 PM5/18/02
to
Apparanty, that does not work in my application. I add the code I am using:

while(!Terminated && (ClientSocket && ClientSocket->Connected)){

try {
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket, CLIENTWAITTIME);
try {


if(pStream->Read(buffer, sizeof(buffer)) > 0){
if (Form1->Debug){
Form1->Memo1->Lines->Add(AnsiString("(Client) ") + AnsiString(buffer));
Form1->Memo1->Lines->Add("Socket-Nr.: " + IntToStr(Sckt));
}// if Debug

Form1->befehl_parse(Sckt, buffer);
}// if pStream

}//try
__finally
{
delete pStream;
}

}//try
catch(...)
{
HandleException();
}
}// while !Terminated

Where is the problem? Any suggestions?
Michael


Frank Birbacher

unread,
May 18, 2002, 7:06:46 PM5/18/02
to
Hi!

michael wrote:
> Well, my if-condition was:
> while(!Terminated && ClientSocket->Connected).

Well, it's a while condition, isn't it?

> When I change the code there is still no difference:


> When the client disconnects and I set a breakpoint to the "if condition line" then > ClientSocket->Connected is still "true"
> and the thread is still active. I can't figure out where the problem is.

I got that, too. Couldn't figure it out either. Posted here, too. Got no
answer to solve the problem. I stick with reading until an exception
arises. Wrap your code into try{...}catch(Exception&){break;}

Frank

Remy Lebeau [TeamB]

unread,
May 19, 2002, 12:56:38 AM5/19/02
to
Please see my other reply, where I already explain why that is and what to
do about it.


Gambit

"Frank Birbacher" <bloodym...@gmx.net> wrote in message
news:3CE6DE86...@gmx.net...

Remy Lebeau [TeamB]

unread,
May 19, 2002, 1:08:43 AM5/19/02
to
Three things I see you not doing from my previous sample:

1) You shouldn't be allocating a new TWinSocketStream in each iteration of
the loop, you should instead be allocating a single instance that the thread
re-uses each time.

2) You're not calling WaitForData() at all.

3) You're not breaking the loop if Read() fails

Btw, it's very dangerous to access components in the main VCL thread like
you are. You must synchronize the access or else you'll run the risk of
severe problems if the main VCL thread tries to access the same components
at the very same time.

Try this instead:


class TMyThread : public TServerClientThread
{
private:
char buffer[1024]; // whatever the real buffer is
void __fastcall Process();
...
};

void __fastcall TMyThread::ClientExecute()
{
TWinSocketStream *pStream = NULL;

try
{
pStream = new TWinSocketStream(ClientSocket, CLIENTWAITTIME);

while(!Terminated && (ClientSocket && ClientSocket->Connected))
{
try
{

if(!pStream->WaitForData(CLIENTWAITTIME))
continue;

if(pStream->Read(buffer, sizeof(buffer)) < 1)
break;

// always sync access to the main VCL thread !!!!!
Synchronize(Process);
}
catch(...)
{
HandleException();
}
}
}
__finally
{
if(pStream)
delete pStream;
}
}

void __fastcall TMyThread::Process()
{
if (Form1->Debug)
{
Form1->Memo1->Lines->Add("(Client) " + AnsiString(buffer));


Form1->Memo1->Lines->Add("Socket-Nr.: " + IntToStr(Sckt));
}

Form1->befehl_parse(Sckt, buffer);
}


Gambit

"Michael" <gr...@dhzb.de> wrote in message news:3ce6d49b$1_1@dnews...

> Apparanty, that does not work in my application. I add the code I
> am using:

<snip>

Michael

unread,
May 19, 2002, 4:12:31 AM5/19/02
to

Thank you for your help. It worked.
I did not really understand the significance of the changes you suggested, so I have to do some thinking. I guess I myself would have been not able to solve this, so thank you again.
Thank you for reminding me on the synchronize aspect, however, these lines were for debugging only, but probably one should do this right from the beginning.
Michael

"Remy Lebeau [TeamB]" <gamb...@yahoo.com> wrote:

Michael

unread,
May 19, 2002, 4:44:51 AM5/19/02
to

see the answer from Remy Lebeau! It solved my problems and the thread stops! Great!
Michael

Frank Birbacher

unread,
May 19, 2002, 5:41:17 PM5/19/02
to
Hi!

Michael wrote:
> see the answer from Remy Lebeau! It solved my problems and the thread stops! Great!

Yeah, I changed my code accordingly, too, and the problem is gone!
THANKS REMY!!

Frank

0 new messages