Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Mar : Re: Creating TCP server with blocking Indy components?
| Subject: | Re: Creating TCP server with blocking Indy components? |
| Posted by: | "Bo Berglund" (bo.berglu..@telia.com) |
| Date: | Sat, 24 Mar 2007 09:11:17 |
On Fri, 23 Mar 2007 18:03:53 -0800, "Remy Lebeau \(TeamB\)"
<no.spam@no.spam.com> wrote:
>
>"Bo Berglund" <bo.berglund@telia.com> wrote in message
>news:nao8031flnt3sv31uk53al06tlu17hqu0r@4ax.com...
>
>> Just downloaded the docs. My-oh-my, it is a 3187 page
>> PDF file and no really useful indexing either....
>
>The Indy-In-Depth eBook is not the documentation I was referring to.
I am not either. I went to the docs link
http://www.indyproject.org/Sockets/Docs/index.aspx
and it contains a hard-to-read PDF with all those pages...
>
>> OK, so the event fires by itself also with no data being received???
>> Strange.
>
>The most common thing done when writing a blocking threaded server is
>to write a 'while not Terminated' loop in the thread. So TIdTCPServer
>does that for you internally, allowing you to focus your code on just
>what happened for each iteration of the loop.
OK, so I stay in the loop eternally then. Can I do like so:
procedure TServerFrmMain.ServerExecute(AThread: TIdPeerThread);
var
sRecData: string;
begin
while not AThread.Terminated and AThread.Connection.Connected then
begin
sRecData := AThread.Connection.ReadLn('</msg>', 2000);
if sRecData = '' then Continue;
do some stuff with RecData like stuffing it into a buffer (how)...
end;
end;
Now I come back to my problem of handling the "comands" the server
needs to *send* to the "client" (it is really a screwy system this
tool maker has designed...):
The connection to the client is maintained in a thread of its own and
my main application needs to send commands to the client at irregular
intervals controlled by things that happen in the main part of the
application. So how can I get hold of that specific connection there
and send the string out?
Should I capture the AThread object in a variable in the main program
when the connection is done (remember, only one allowed connection)
and later use its methods via the variable?
What will happen with the threading model then? Will my main
application again be locked up? Or can I do it the way I outline
below?
They have designed the system so that any command sent to the client
will result in two things:
1) An "immediate" same socket reply from the client (acts more like a
server here...) with an acknowledge or some easily accessible data.
2) At a later time a message on the other socket from the client where
the result of a lengthy operation is supplied intermixed with other
status messages. None of these need to be responded to.
I guess that the type 2 messages will be like normal server activity
and I can handle that by reading the data and not replying at all. So
I don't need to stay in any loop, just handle it in the OnExecute
event?
The concern now is the type 1 handling, i.e. how to send a message
from the main application using the thread that is in an eternal loop.
Would this work:
Private variables in the form level:
FClientConnected,
FMessageToSend: boolean; {global flags}
FMessageText: string; {global message container string}
procedure TServerFrmMain.ServerConnect(AThread: TIdPeerThread);
begin
FClientConnected := true;
while not AThread.Terminated and AThread.Connection.Connected then
begin
if FMessageToSend then
begin
AThread.Connection.Write(FMessageText);
FMessageToSend := false; {reset semaphore}
end;
end;
FClientConnected := false;
end;
Then in the main application:
procedure TServerFrmMain.SendCommand(Command: string): boolean;
var
begin
Result := false;
if not FClientConnected then exit;
try
while FMessageToSend do {wait until previous message is done}
begin
Sleep(1);
Application.ProcessMessages;
end;
FMessageText := Command;
FMessageToSend := true;
Result := true;
except
end;
end;
Then any message that arrives from the connected client on any of the
two channels have to be put into some list container that is examined
in the main application somehow in order not to tie up the socket
thread with that.
How can I make sure that I am not accessing this list in the main
application when the thread is also doing so? Using semaphores like
above?
>> It contains a lot of extraneous files as well, which the 9.0.18 zip
>> does not.
>
>Such as?
Such as 80 files in a sub dir "Boxter" and below that.
And 1 file in a subdir SyncObjs
These directories are not present at all in the 9.0.18 zipfile.
>> Are there real improvements to the dev snapshot?
>
>Yes. Many of the units have received updates since 9.0.18 was
>released in late 2004.
OK, so I need 9.0.50 then....
Thanks,
Bo
none