 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Bo Berglund Guest
|
Posted: Wed May 02, 2007 11:58 pm Post subject: A TCP server using Indy, which really should be a client.... |
|
|
I had a thread here back in March concerning a weird socket
communication setup that I tried to use Indy for. Unfortunately the
thread died out before I received the final knowledge I need and
tomorrow I have to discuss this in the dev group so here I go again...
Parts of the below text is from the last posting of the thread back in
March, parts are new.
Background
----------
A Machine Tool maker has designed a remote control communications
scheme for his machine as follows:
There will be two socket channels opened between the machine and a
host computer that will be controlling the machine.
One channel is a control channel over which commands will be sent to
the machine to tell it to do certain things. These commands will
always be responded to immediately as a handshake.
The other channel is a message channel on which the machine will send
data either spontaneously or as requested over the command channel.
These messages are not responded to, just received.
The weird thing about this design is that the machine is acting as a
socked *client* and we are expected to build our software as a socket
*server*. Upon startup of the machine it will be trying to connect to
the command channel of the host PC "server". When successfully
connected it is supposed to get a command to tell it to connect to the
message channel as well.
From now on the system is such that the "server" (our software) is
supposed to send messages as commands on the command channel and this
is supposed to trigger actions in the machine (client) that will send
back data and do something physically.
The whole thing is really backwards, but we are not in a position to
change that. :-(
Current situation
------------------
I tried to apply Indy TIdTCPServer to this and I have been struggling
through the non-blocking versus blocking paradigm shift back in March.
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 on the server 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 host 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 (only one allowed connection) and later
use its methods via the variable?
What will happen with the threading model then? Will my main
application 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.
I would really like to have a good suggestion on how to originate a
message from the tcp server side towards the client instead of
responding to something the client has sent!
/Bo B |
|
| Back to top |
|
 |
|
|
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
|
|