Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Mar : Re: Looking for client/server demo of a proprietary protocol based on TIdCmdTCPS
| Subject: | Re: Looking for client/server demo of a proprietary protocol based on TIdCmdTCPS |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Fri, 24 Mar 2006 12:51:38 |
"Maxim Shiryaev" <maxim@olma-press.ru> wrote in message
news:4423f949@newsgroups.borland.com...
> Let's I have a commad "GETDATA". It replies like:
>
> 200 OK
> Result1=some string
> Result2=another string
> .
<snip>
> Now I need to create a client. I want to pass some data (also
> encoded in TStrings) to my server and get the results back.
You need to use the WriteRFCStrings() and Capture() methods. For example:
--- server ---
uses
IdObjs, IdSys;
procedure TForm1.CommandGETDATA(ASender: TIdCommand);
var
LParams: TIdStringList;
begin
LParams := TIdStringList.Create;
try
ASender.Context.Connection.IOHandler.Capture(LParams);
// use LParams as needed...
ASender.Reply.SetReply(200, 'OK');
ASender.Response.Add('Result1=some string');
ASender.Response.Add('Result2=another string');
finally
Sys.FreeAndNil(LParams);
end;
end;
--- client ---
uses
IdObjs, IdSys;
var
LParams, LData: TIdStringList;
begin
LParams := TIdStringList.Create;
try
LData := TIdStringList.Create;
try
LParams.Add('Param1=value1');
LParams.Add('Param2=value 2');
IdTCPClient1.WriteLn('GETDATA');
IdTCPClient1.IOHandler.WriteRFCStrings(LParams);
IdTCPClient1.GetResponse(200);
IdTCPClient1.IOHandler.Capture(LData);
// use LData as needed ...
finally
Sys.FreeAndNil(LData);
end;
finally
Sys.FreeAndNil(LParams);
end;
end;
With that said, it would be better if you put the params in the command
directly, not send them afterwards. The SendCmd() and CommandHandler
architectures are well-designed for that approach. For example:
GETDATA value1 value2
200 OK
some string
another string
.
--- server ---
uses
IdObjs, IdSys;
// make sure the TIdCommandHandler.ParseParams property is set to True
procedure TForm1.CommandGETDATA(ASender: TIdCommand);
var
I: Integer;
begin
for I := 0 to ASender.Params.Count do
begin
// use ASender.Params[I] as needed ...
end;
ASender.Reply.SetReply(200, 'OK');
ASender.Response.Add('some string');
ASender.Response.Add('another string');
end;
--- client ---
uses
IdObjs, IdSys;
var
LData: TIdStringList;
begin
LData := TIdStringList.Create;
try
IdTCPClient1.SendCmd('GETDATA value1 value2', 200);
IdTCPClent1.IOHandler.Capture(LData);
// use LData as needed ...
finally
Sys.FreeAndNil(LData);
end;
end;
If you need to send parameters that have spaces in them, then either:
1) define a unique value for the TIdCommandHandler.ParamDelimiter property
that will never appear in your parameter data:
GETDATA value1|value 2
200 OK
some string
another string
.
--- server ---
uses
IdObjs, IdSys;
procedure TForm1.CommandGETDATA(ASender: TIdCommand);
var
I: Integer;
begin
for I := 0 to ASender.Params.Count do
begin
// use ASender.Params[I] as needed ...
end;
ASender.Reply.SetReply(200, 'OK');
ASender.Response.Add('some string');
ASender.Response.Add('another string');
end;
--- client ---
uses
IdObjs, IdSys;
var
LData: TIdStringList;
begin
LData := TIdStringList.Create;
try
IdTCPClient1.SendCmd('GETDATA value1|value 2', 200);
IdTCPClent1.IOHandler.Capture(LData);
// use LData as needed ...
finally
Sys.FreeAndNil(LData);
end;
end;
2) use set the TIdCommandHandler.ParseParams property to False and then
parse the TIdCommand.UnparsedParams property manually.
GETDATA value1 "value 2"
200 OK
some string
another string
.
--- server ---
uses
IdObjs, IdSys;
procedure TForm1.CommandGETDATA(ASender: TIdCommand);
var
LTmp, LParam: String;
begin
LTmp := Sys.Trim(ASender.UnparsedParams);
while LTmp <> '' do
begin
if LTmp[1] = '"' then begin
Delete(LTmp, 1, 1);
LParam := Fetch(LTmp, '"');
end else begin
LParam := Fetch(LTmp, ' ');
end;
// use LParam as needed ...
LTmp := Sys.TrimLeft(LTmp);
end;
ASender.Reply.SetReply(200, 'OK');
ASender.Response.Add('some string');
ASender.Response.Add('another string');
end;
--- client ---
uses
IdObjs, IdSys;
var
LData: TIdStringList;
begin
LData := TIdStringList.Create;
try
IdTCPClient1.SendCmd('GETDATA value1 "value 2"', 200);
IdTCPClent1.IOHandler.Capture(LData);
// use LData as needed ...
finally
Sys.FreeAndNil(LData);
end;
end;
Gambit