Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Mar : Re: Looking for client/server demo of a proprietary protocol based on TIdCmdTCPS

www.cryer.info
Managed Newsgroup Archive

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:Sun, 26 Mar 2006 14:13:03

"Maxim Shiryaev" <MaximShiryaev@mail.ru> wrote in message
news:44250cf5$1@newsgroups.borland.com...

> The parameters will actually be UTF-8 strings decoded back
> to WideStrings at a server.

That is fine.  A lot of protocols that support Unicode do that nowadays.

> So each parameter on individual line seems to be easier to parse.

As you have already seen, that is technically doable.  But I do not
recommend that approach in general.  It actually complicates the design of
your protocol, not makes it simplier.

> More over the number of parameters will be variable (I don't want
> to pass default values).

Having everything on a single line can handle that just as easily as using
separate lines.

> And they will be name-bound, not positional.

The examples I showed you earlier can be adapted to handle names inside the
parameters.  In fact, the TIdCommand.Params property is a TStrings
descendant, so you can make use of its Values[] sub-property, ie:

    GETDATA Param1=value1 Param3=value3

    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
        Param1, Param3: String
    begin
        Param1 = ASender.Params.Values['Param1'];
        Param3 = ASender.Params.Values['Param3'];
        //...
        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 Param1=value1 Param3=value3',
200);
            IdTCPClent1.IOHandler.Capture(LData);
            // use LData as needed ...
        finally
            Sys.FreeAndNil(LData);
        end;
    end;


Alternatively:

    --- server ---

    uses
        IdObjs, IdSys;

    // make sure the TIdCommandHandler.ParseParams property is set to True
    procedure TForm1.CommandGETDATA(ASender: TIdCommand);
    var
        I: Integer;
        ParamName, ParamValue: String
    begin
        for I := 0 to ASender.Params.Count-1 do
        begin
            ParamValue := ASender.Params[I];
            ParamName := Fetch(ParamValue, '=');
            // use ParamName and ParamValue as needed ...
        end;
        ASender.Reply.SetReply(200, 'OK');
        ASender.Response.Add('some string');
        ASender.Response.Add('another string');
    end;


> So I've decided to make the command ASCII only and pass parameters
> on additional lines.

I still do not recommend that approach.  But it is your decision, not mine.

> It looks like we need an extended version of TIdTCPClient.

No, you do not.

> The current one lacks functions compared to its server counterpart.

As it should be, because TIdTCPClient is not a server component.  However,
Indy 10 does have a TIdCmdTCPClient component, which has the exact same
CommandHandler support that TIdCmdTCPServer has.

> For example, an overloaded version of
>
>   SendCmd(Command : string; Parameters: array of string;
>      Header: TStrings=nil; Body: TStrings=nil)
>
> would be very useful.

No, it wouldn't.  For starters, it would complicate TIdTCPClient itself.
And second, it has no use in any other Indy component at all, so there is no
reason to put it into Indy directly.  What you ask for is custom behavior,
and as such you should be wrapping that kind of functionality in your own
function that formats the necessary values for the existing SendCmd() to
use.

> Can you give me some link to the docs about RFC-based protocols

Every protocol is described in its own separate RFC.  The documentation
lists which component implements which RFCs.

> describing how to create a new application-level one.

There are no docs for that.

> All I found in Google are HTTP references. They describe structure of
> commands, headers, body, staus codes. etc.

That is what RFCs do to begin with.

> But I need a more general description.

Such as?


Gambit

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive