BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to initiate a message from a TIdTCPServer to a client?

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock
View previous topic :: View next topic  
Author Message
Bo Berglund
Guest





PostPosted: Thu May 03, 2007 12:50 am    Post subject: How to initiate a message from a TIdTCPServer to a client? Reply with quote



Simplifying my question from the previous post I did:

Assuume that I have a server using the TIdTCPServer component that has
a connected client (one single client).

How can I send an asynchronous message from the server to the
connected client without blocking the complete server? This is not a
message in response to a client call, it is totally spontaneous and
asynchronous to the client.

Somehow I have to:
- Get hold of the AThread object for the client connection
- Tell the thread to send the message (a string)
- Do it such that only the client thread is blocked, not my main
server application.

Any guidelines?

I am using Delphi 7 Pro with the Indy 9 components that came with the
Delphi install.
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu May 03, 2007 1:13 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote



"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:9fqh335cpq0ump2kvfso5jcah6anlmsfb0 (AT) 4ax (DOT) com...

Quote:
How can I send an asynchronous message from the server to
the connected client without blocking the complete server? This
is not a message in response to a client call, it is totally
spontaneous and asynchronous to the client.

Examples of doing exactly that have been posted many times before. Go
to http://www.deja.com and search through the newsgroup archives.

Quote:
Somehow I have to:
- Get hold of the AThread object for the client connection

You can get that from the server's Threads property.

Quote:
- Tell the thread to send the message (a string)

Examples of both 1) sending the data immediately, and 2) queuing the
data for the OnExecute event to send later, have been posted before.

Quote:
- Do it such that only the client thread is blocked, not my
main server application.

Using a per-client queue then.


Gambit
Back to top
Bo Berglund
Guest





PostPosted: Thu May 03, 2007 1:42 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote



On Wed, 2 May 2007 13:13:52 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:

"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:9fqh335cpq0ump2kvfso5jcah6anlmsfb0 (AT) 4ax (DOT) com...

How can I send an asynchronous message from the server to
the connected client without blocking the complete server? This
is not a message in response to a client call, it is totally
spontaneous and asynchronous to the client.

Examples of doing exactly that have been posted many times before. Go
to http://www.deja.com and search through the newsgroup archives.

The only thing I found is this:

<quote>
For example... assuming that you wish to send the message to all
clients connected to the server... the code would look like:

TidThreadMgr.Lock.Acquire; // lock the list
for x:=0 to TidThreadMgr.ActiveThreads[x].Count-1 do

TidPeerThread(TidThreadMgr.ActiveThreads[x]).Connection.WriteLn('Button
Clicked');
TidThreadMgr.Lock.Release;
</quote>

Of course this will hit only one client in my case since there will
only be one connected...

Is this the recommended way to do it?
How do I connect a TIdThreadMgr object to my server? The example seems
odd, since I had expected an instance rather than a class name.

Quote:

Examples of both 1) sending the data immediately,

That is what i am after, but I don't know how to wade through the NG
to find it...

Quote:
and 2) queuing the
data for the OnExecute event to send later, have been posted before.

OnExecute does me no good since by definition (in this case) the
client is silent unless being spoken to from the server...
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu May 03, 2007 2:09 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:rith331d88730ubl1d8jr0e56dugh2134e (AT) 4ax (DOT) com...

Quote:
The only thing I found is this:

What search criteria did you use? That is not what you are asking
for. I have posted extensive examples of sending asynchronous
per-client messages before.

Quote:
How do I connect a TIdThreadMgr object to my server?

TIdTCPServer has a ThreadMgr property. But you don't need to use
that. TIdTCPServer creates its own ThreadMgr object automatically
when it is activated. That code shouldn't have been accessing
TIdThreadMgr directly in the first place.

Quote:
That is what i am after, but I don't know how to wade through
the NG to find it...

It is all a matter of searching the right criteria. For instance,
this posting took only a few seconds to find:


http://groups.google.com/group/borland.public.delphi.internet.winsock/msg/f81187d9a57baec4

Quote:
OnExecute does me no good

Yes, it does. OnExecute is triggered in a continuous loop for the
lifetime of the connection, regardless of whether the client does
anything.

Quote:
by definition (in this case) the client is silent unless being
spoken to from the server...


Doesn't matter. It doesn't need to do anything in order for the
OnExecute event to work.


Gambit
Back to top
Bo Berglund
Guest





PostPosted: Thu May 03, 2007 2:57 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Wed, 2 May 2007 14:09:57 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:rith331d88730ubl1d8jr0e56dugh2134e (AT) 4ax (DOT) com...

The only thing I found is this:

What search criteria did you use? That is not what you are asking
for. I have posted extensive examples of sending asynchronous
per-client messages before.

"TIdTCPServer client communication"

it produced a number of hits, and the first hit contained the code I
quoted.

Quote:
How do I connect a TIdThreadMgr object to my server?

TIdTCPServer has a ThreadMgr property. But you don't need to use
that. TIdTCPServer creates its own ThreadMgr object automatically
when it is activated. That code shouldn't have been accessing
TIdThreadMgr directly in the first place.

True, I found out that the server component did have a property
ThreadMgr, which is what the code was all about. However it did not
have the property ActiveThreads so it was useless after all...
I guess the example was for Indy 8 or something based on the age of
the posting.

Quote:
That is what i am after, but I don't know how to wade through
the NG to find it...

It is all a matter of searching the right criteria. For instance,
this posting took only a few seconds to find:


http://groups.google.com/group/borland.public.delphi.internet.winsock/msg/f81187d9a57baec4

That is from our earlier exchange and it popped up also in my search,
but was irrelevent since I already had that.

By the way, I use Forte Free Agent as newsreader and I have cache of
borland.public.delphi.internet.winsock postings from some time back in
Agent. But there are limited ways of searching in Agent, basically
only on authors and subjects...

Quote:
OnExecute does me no good

Yes, it does. OnExecute is triggered in a continuous loop for the
lifetime of the connection, regardless of whether the client does
anything.

????
It seems totally contradictory to me. OnExecute by its name should be
an event firing when there are data arriving from the client, right?
Since no data are arriving it doesn't get fired and I cannot do
anything in it. Or is it fired when data arrives AND every x
milliseconds or so? In that case what is X and how is it set?

If I want to handle data that ARE arriving from the client (after the
client receives the command I want to send, it is supposed to talk
back to acknowledge the reception), then how can I differentiate
between these two? (between the OnExecute that happens by magic and
has no cause in received data from the OnExecute that fires when data
have in fact arrived)???

The mist lowers around my head, I am probably too old to be doing
this....


Quote:
by definition (in this case) the client is silent unless being
spoken to from the server...

Doesn't matter. It doesn't need to do anything in order for the
OnExecute event to work.

As above, how can the server then see the difference if it does send

data?
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu May 03, 2007 3:53 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:sa1i33914s3n2ermhukcv1pkhendproj3a (AT) 4ax (DOT) com...

Quote:
"TIdTCPServer client communication"

That is not good search criteria to use for what you are asking for.
It does not narrow down the type of communication you want to
accomplish.

Quote:
True, I found out that the server component did have a property
ThreadMgr, which is what the code was all about. However it did
not have the property ActiveThreads so it was useless after all...

TIdThreadMgr does have an ActiveThreads property in Indy 9.

Quote:

http://groups.google.com/group/borland.public.delphi.internet.winsock
/msg/f81187d9a57baec4

That is from our earlier exchange and it popped up also in my
search,
but was irrelevent since I already had that.

It is not irrelevant. Look at your current requirements. The code in
the posting I mentioned does exactly what those requirements say to
do:

- Get hold of the AThread object for the client connection

List := IdTCPServer1.Threads.LockList;
try
Thread := TIdPeerThread(List[SomeIndex]);
...
finally
IdTCPServer1.Threads.UnlockList;
end;

- Tell the thread to send the message (a string)

TIdThreadSafeStringList(Thread.Data).Add('your data here');

- Do it such that only the client thread is blocked, not my main
server application.

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
List: TIdStringList;
begin
List := TIdThreadSafeStringList(AThread.Data).Lock;
try
AThread.Connection.WriteStrings(List);
finally
List.Clear;
TIdThreadSafeStringList(AThread.Data).Unlock;
end;
end;

Quote:
By the way, I use Forte Free Agent as newsreader and I have cache of
borland.public.delphi.internet.winsock postings from some time back
in
Agent. But there are limited ways of searching in Agent, basically
only on authors and subjects...

Which is why I always use Deja. It has a very flexible search engine,
and the archives go back many years.

Quote:
Yes, it does. OnExecute is triggered in a continuous loop for the
lifetime of the connection, regardless of whether the client does
anything.

????
It seems totally contradictory to me.

Not when you take into account why it was designed that way to begin
with. In common socket programming, especially when dealing with
blocking sockets, such looping is usually used in developer's code.
So TIdTCPServer (and Indy in general) was designed to handle all of
the necessary looping for the developer. So in this case, the
OnExecute's code only has to focus on the operations needed for a
specific iteration of the loop and then exit, and it will be triggered
again on the next iteration. This keeps the developer's code smaller
and more focused.

Quote:
OnExecute by its name should be an event firing when there are data
arriving from the client, right?

No. Such a requirement would make more sense for an OnWrite or OnData
event instead. OnExecute implies that the server has to do something,
anything, with the connection in general. It is up to the server to
decide what to actually do.

Quote:
Since no data are arriving it doesn't get fired

Yes, it does trigger the OnExecute event even if data is not arriving.
You can verify that for yourself very easily. Simply put a Beep() in
it and you will hear it beeping continously.

Quote:
Or is it fired when data arrives AND every x milliseconds or so?

Like I said, it is triggered in a continous loop. As soon as the
event handler exits, it is triggered again if the client is still
connected. There is no waiting.

Quote:
If I want to handle data that ARE arriving from the client (after
the
client receives the command I want to send, it is supposed to talk
back to acknowledge the reception), then how can I differentiate
between these two?

The OnExecute event handler can query the connection to see if it has
pending data to read, for example:

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
AThread.Connection.IOHandler.ReadFromStack(True, 0, False);
if AThread.Connection.InputBuffer.Size > 0 then
begin
// process inbound data as needed...
end;
// send queued outbound data as needed...
end;


Gambit
Back to top
Bo Berglund
Guest





PostPosted: Thu May 03, 2007 8:11 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Wed, 2 May 2007 15:53:47 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:
var
List: TIdStringList;

Tried your code example but Delphi complained about TIdStringList
being an unknown identifier.
The help did not help either, seems not to exist....

Sorry to be a pest, but I need to get this working and I am so unused
to Indy servers....


Bo Berglund
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu May 03, 2007 8:11 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:8ssi335ik3r97ec3uptvlvciu66k6u8tda (AT) 4ax (DOT) com...

Quote:
Tried your code example but Delphi complained about
TIdStringList being an unknown identifier.

TIdThreadSafeStringList.Lock() returns a TStringList in Indy 9. It
returns a TIdStringList in Indy 10.


Gambit
Back to top
Bo Berglund
Guest





PostPosted: Fri May 04, 2007 12:17 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Thu, 3 May 2007 01:03:54 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:

"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:8ssi335ik3r97ec3uptvlvciu66k6u8tda (AT) 4ax (DOT) com...

Tried your code example but Delphi complained about
TIdStringList being an unknown identifier.

TIdThreadSafeStringList.Lock() returns a TStringList in Indy 9. It
returns a TIdStringList in Indy 10.


I solved that by searching the Indy10 sources and then I added this to
a type declaration section:
TIdStringList = Classes.TStringList;

Then I had another problem with the code as explained in the snippet
below:

procedure TMachineComm.srvCommandExecute(AThread: TIdPeerThread);
{Handler for client calls (calls are responses to commands)}
var
sRecData: string;
List: TIdStringList;
begin
{*** This is eternally executed as long as a client is connected.}
if not AThread.Terminated and AThread.Connection.Connected then
begin
{Receive data from client}
{**** The line below did not compile, probably an Indy10 construct}
//AThread.Connection.IOHandler.ReadFromStack(True, 0, False);
if AThread.Connection.InputBuffer.Size > 0 then
begin
{**** I never get here at all when the client sends data!}
sRecData := '';
sRecData := AThread.Connection.ReadLn('</msg>', 2000);
if sRecData <> '' then
AddCmdResponse(sRecData);
end;

{Send dtata to client}
{*** Not tested yet if this works or not}
List := TIdThreadSafeStringList(AThread.Data).Lock;
try
if List.Count > 0 then
AThread.Connection.WriteStrings(List);
finally
List.Clear;
TIdThreadSafeStringList(AThread.Data).Unlock;
{*** If I don't put the Sleep(1) here the CPU use goes to 100%!!!!}
Sleep(1);
end;
end;
end;

So the most important item here is that I am probably lacking the
Indy9 version of AThread.Connection.IOHandler.ReadFromStack, what can
that be called? Now the InputBuffer never gets above zero so no
meassages are received.

I was surprised that the Indy implementation was such that the thread
consumes 100% CPU cycles when a client was connected. I had to put in
a Sleep(1) to stop that. My laptop started to go into warp and the fan
wound up to max speed....


Bo Berglund
Back to top
Bo Berglund
Guest





PostPosted: Fri May 04, 2007 3:25 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Thu, 03 May 2007 21:17:45 +0200, Bo Berglund
<bo.berglund (AT) system3r (DOT) se> wrote:

Quote:
if not AThread.Terminated and AThread.Connection.Connected then
begin
{Receive data from client}
{**** The line below did not compile, probably an Indy10 construct}
//AThread.Connection.IOHandler.ReadFromStack(True, 0, False);

But this does:
AThread.Connection.ReadFromStack(True, 0, False);

Quote:
if AThread.Connection.InputBuffer.Size > 0 then
begin
{**** I never get here at all when the client sends data!}
Now I do, see above.


Quote:
sRecData := '';
sRecData := AThread.Connection.ReadLn('</msg>', 2000);

Since the data I sent happened to have a CRLF tacked to the end of the
message, I got here twice. The first time I got the message minus the
end tag and the second time there were still 2 bytes in the
InputBuffer. So it called the ReadLn but it couldn't get the tag so I
expected it to time out after 2 seconds, but in fact there was no time
out at all. Instead it hung there until I sent another message with
the end tag inside.
Should it not return after the 2000 ms timeout?

/Bo
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri May 04, 2007 5:25 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:kqck331f5uft42l6js5vm53umsvqosuj63 (AT) 4ax (DOT) com...

Quote:
I solved that by searching the Indy10 sources and then I added this
to
a type declaration section:
TIdStringList = Classes.TStringList;

You did not need to do that. You are using Indy 9, which is evident
by your use of TIdPeerThread, which doesn't exist in Indy 10. Like I
said earlier, TIdThreadSafeStringList.Lock() returns a TStringList in
Indy 9, not a TIdStringList. So just update the example code
accordingly:

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
List: TStringList; // <-- here
begin
List := TIdThreadSafeStringList(AThread.Data).Lock;
try
AThread.Connection.WriteStrings(List);
finally
List.Clear;
TIdThreadSafeStringList(AThread.Data).Unlock;
end;
end;

Quote:
Then I had another problem with the code as explained in the
snippet below:

?

Quote:
if not AThread.Terminated and AThread.Connection.Connected then

Get rid of that completely.

Quote:
{**** The line below did not compile, probably an Indy10 construct}
//AThread.Connection.IOHandler.ReadFromStack(True, 0, False);

No, it is not an Indy 10 construct. ReadFromStack() is a method of
TIdTCPConnection, not TIdIOHandler:

AThread.Connection.ReadFromStack(True, 0, False);

Quote:
if AThread.Connection.InputBuffer.Size > 0 then
begin
{**** I never get here at all when the client sends data!}

That is because you commeted out the call to ReadFromStack(). Without
that, no data will ever be read from the socket and put into the
InputBuffer.

Quote:
if List.Count > 0 then

You don't need that. WriteString() handles that internally.

Quote:
{*** If I don't put the Sleep(1) here the CPU use goes to 100%!!!!}

That is because you commented out the call to ReadFromStack() and are
thus running a tight unyielding loop without the call to Sleep().
ReadFromStack() has a timeout parameter that puts the calling thread
into an efficient waiting state until data arrives or the timeout
expires. Uncomment the call to ReadFromStack() and use its timeout
parameter. Then you can remove the call to Sleep().

Quote:
I was surprised that the Indy implementation was such that
the thread consumes 100% CPU cycles when a client was
connected.

That is because you are running your thread very tightly without
performing any yielding operations to give time slices to other
threads. Performing a blocking socket call is a yielding operation.
So is calling Sleep().


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri May 04, 2007 5:31 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:7vnk33puisucfgecc8t1ktn3f0q8ch25e1 (AT) 4ax (DOT) com...

Quote:
Since the data I sent happened to have a CRLF tacked to the
end of the message, I got here twice.

Will that always be the case? If so, then simply put the CRLF into
your terminator string, ie:

sRecData := AThread.Connection.ReadLn('</msg>' + EOL);

Otherwise, you can manually strip it out from the InputBuffer if it is
present, ie:

sRecData := AThread.Connection.ReadLn('</msg>');
if AThread.Connection.InputBuffer.Size >= 2 then
begin
if StrLComp(PChar(AThread.Connection.InputBuffer.Memory,
PChar(EOL), 2)) = 0 then
AThread.Connection.InputBuffer.Remove(2);
end;

Quote:
The first time I got the message minus the end tag and the second
time there were still 2 bytes in the InputBuffer.

Because you did not read them from the InputBuffer beforehand. Since
your messages are already delimited by start/end tags anyway, you
don't really need the CRLF in between them at all. You might consider
taking that out of your protocol altogether.

Quote:
I expected it to time out after 2 seconds, but in fact there was no
time out at all.


Yes, there will be a timeout, and the ReadLnTimedOut property will be
set to True accordingly.


Gambit
Back to top
Bo Berglund
Guest





PostPosted: Fri May 04, 2007 8:11 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Thu, 3 May 2007 17:31:57 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:7vnk33puisucfgecc8t1ktn3f0q8ch25e1 (AT) 4ax (DOT) com...

Since the data I sent happened to have a CRLF tacked to the
end of the message, I got here twice.

Will that always be the case? If so, then simply put the CRLF into
your terminator string, ie:

sRecData := AThread.Connection.ReadLn('</msg>' + EOL);

Yes, if the CRLF is there always, but I don't know that.

Quote:
Otherwise, you can manually strip it out from the InputBuffer if it is
present, ie:

sRecData := AThread.Connection.ReadLn('</msg>');
if AThread.Connection.InputBuffer.Size >= 2 then
begin
if StrLComp(PChar(AThread.Connection.InputBuffer.Memory,
PChar(EOL), 2)) = 0 then
AThread.Connection.InputBuffer.Remove(2);
end;

I'll try that.

Quote:
The first time I got the message minus the end tag and the second
time there were still 2 bytes in the InputBuffer.

Because you did not read them from the InputBuffer beforehand. Since
your messages are already delimited by start/end tags anyway, you
don't really need the CRLF in between them at all. You might consider
taking that out of your protocol altogether.

I have no influence over the protocol data, it is specified by a
machine maker...
His documentation is a bit terse too, basically a word document
outlining the XML structure in a "readable" way. But details like the
existence of CRLF is not there. Of course once we can hook up to a
machine we will see, but I'd prefer to solve this in advance.

Right now I am also building a machine simulator so we can do some
tests....
Back to top
Bo Berglund
Guest





PostPosted: Fri May 04, 2007 8:11 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

On Thu, 3 May 2007 17:25:19 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote:

Quote:

"Bo Berglund" <bo.berglund (AT) system3r (DOT) se> wrote in message
news:kqck331f5uft42l6js5vm53umsvqosuj63 (AT) 4ax (DOT) com...

I solved that by searching the Indy10 sources and then I added this
to
a type declaration section:
TIdStringList = Classes.TStringList;

Now taken away.

Quote:

You did not need to do that. You are using Indy 9, which is evident
by your use of TIdPeerThread, which doesn't exist in Indy 10. Like I
said earlier, TIdThreadSafeStringList.Lock() returns a TStringList in
Indy 9, not a TIdStringList. So just update the example code
accordingly:

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
List: TStringList; // <-- here

OK, works.

Quote:
begin
List := TIdThreadSafeStringList(AThread.Data).Lock;
try
AThread.Connection.WriteStrings(List);
finally
List.Clear;
TIdThreadSafeStringList(AThread.Data).Unlock;
end;
end;


if not AThread.Terminated and AThread.Connection.Connected then

Get rid of that completely.

Won't there be an exception on the following lines if reads are done
on a closed socket?

Quote:
AThread.Connection.ReadFromStack(True, 0, False);

Found it..

Quote:

if AThread.Connection.InputBuffer.Size > 0 then
begin
{**** I never get here at all when the client sends data!}

That is because you commeted out the call to ReadFromStack(). Without
that, no data will ever be read from the socket and put into the
InputBuffer.

Yes, that was because the code example was for Indy10 while I have
Indy9. After finding that all I needed was to remove IOHandler it
worked.

Quote:

if List.Count > 0 then

You don't need that. WriteString() handles that internally.

Will check.

Quote:

{*** If I don't put the Sleep(1) here the CPU use goes to 100%!!!!}

That is because you commented out the call to ReadFromStack() and are
thus running a tight unyielding loop without the call to Sleep().
ReadFromStack() has a timeout parameter that puts the calling thread
into an efficient waiting state until data arrives or the timeout
expires. Uncomment the call to ReadFromStack() and use its timeout
parameter. Then you can remove the call to Sleep().

I set the timeout to 2 ms and the CPU cycle usage is now OK.

Thanks for your help! Smile
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Fri May 04, 2007 8:11 am    Post subject: Re: How to initiate a message from a TIdTCPServer to a clien Reply with quote

"Bo Berglund" <bo.berglund (AT) telia (DOT) com> wrote in message
news:q3il339f79a18o2tkl5sqoeroureg48pe0 (AT) 4ax (DOT) com...

Quote:
Won't there be an exception on the following lines if reads are done
on a closed socket?

Yes, but that is ok. Indy is specifically designed to work with, and
rely on, exceptions, especially those that it raises on its own. So
just let it happen. The exception will escape back into the server,
which will then disconnect the socket and shut down the thread
accordingly.


Gambit
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.