Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Mar : Re: INDY TIdTCPClient and TIdTCPServer Usage
| Subject: | Re: INDY TIdTCPClient and TIdTCPServer Usage |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Mon, 20 Mar 2006 11:47:51 |
"Dennis" <marianndkc@home3.gvdnet.dk> wrote in message
news:441eb092$1@newsgroups.borland.com...
> I am able to connect and send one string with the SendCMD method.
> The problem is that the method fails returning because it does not accept
> the answer from the server.
That is because the server code is not writing back its response data in a
format that TIdTCPClient.SendCmd() recognizes.
> IdTCPClient1.SendCmd('Hello', 'OK');
That will not work. For a plain TIdTCPClient, SendCmd() expects numeric
values, not strings, for the server's response code. The only protocols
that Indy implements that use string-based response codes are POP3 and
IMAP4. Every other protocol uses numeric values instead.
> //RichEdit1.Lines.Add('OnExecute triggered');
> RichEdit1.Lines.Add(lCmd);
Neither of those lines are thread-safe. You need to use TIdSync to access
the GUI objects in a thread-safe manner.
> The client raises an exception "Reply code is not valid: OK".
As it should be, because you are not using the correct type of response
codes..
Use this code instead:
--- client ---
IdTCPClient1.SendCmd('Hello', 200);
--- server ---
type
TCmdSync = class(TIdSync)
protected
FCmd: String;
procedure DoSynchronize; override;
public
constructor Create(const ACmd: String); reintroduce;
class procedure Add(const ACmd: String);
end;
constructor TCmdSync.Create(const ACmd: String);
begin
inherited Create;
FCmd := ACmd;
end;
procedure DoSynchronize;
begin
Form1.RichEdit1.Lines.Add(FCmd);
end;
class procedure TCmdSync.Add(const ACmd: String);
begin
with Create(ACmd) do try
Synchronize;
finally
Free;
end;
end;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
lCmd: string;
begin
lCmd := Trim(AContext.Connection.IOHandler.ReadLn);
TCmdSync.Add(lCmd);
AContext.Connection.IOHandler.WriteLn('200 Welcome');
end;
Now, with that said, you should consider using TIdCmdTCPServer instead of
TIdTCPServer. The CommandHandlers mechanism is specifically designed for
the types of protocols that SendCmd() supports. You can define a
CommandHandler item for each command that you want to support, complete with
full design-time support, automated parameter parsing, and automated
replying. All you would have to do in your code is implement the OnCommand
event handlers to perform the operations that the commands are requesting,
and then assign the response data. For example:
--- server ---
// add a HELLO CommandHandler to the TIdCmdTCPServer.CommandHandlers
// proeprty at design-time, and then assign the following as its
OnCommand event handler
procedure TForm1.IdCmdTCPServer1CommandHELLO(ASender: TIdCommand);
begin
TCmdSync.Add('HELLO Received');
ASender.Reply.SetReply(200, 'Welcome');
end;
Gambit