Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Aug : Re: idTCPClient & idTCPServer

www.cryer.info
Managed Newsgroup Archive

Re: idTCPClient & idTCPServer

Subject:Re: idTCPClient & idTCPServer
Posted by:"Remy Lebeau (TeamB)" (no.spam@no.spam.com)
Date:Tue, 15 Aug 2006 13:44:46

"Ian Groves" <ian@REMOVE_THIS_BITigroves.f9.co.uk> wrote in message
news:44e1c0d5@newsgroups.borland.com...

> Indy 10.0.0.52

That is an old version.  You should consider upgrading to the 101.5
snapshot.

> When 2 clients connect i cant determine which one I am dealing with

That is what the TIdContext parameter is for.

> as aUsername and aPassword are clearerd each time some data is sent

As they should be, since they are local variables to the event handler and
will go out of scope when the handler exits.  You have to store your values
outside of the event handler in order to persist them.

> I presume i need to attach this info to AContext somehow

That is one way to do it.

> but how do I do this.

TIdContext has a Data property that you can use.  Create a new class that
holds your per-connection information, and then instantiate that class in
the server's OnConnect event and free it in the OnDisconnect event, ie:

    type
        TMyData = class
        public
            UserName: String;
            Password: String;
        end;

    procedure TMainForm.IdTCPServer1Connect(AContext: TIdContext);
    begin
        AContext.Data := TMyData.Create;
    end;

    procedure TMainForm.IdTCPServer1Disconnect(AContext: TIdContext);
    begin
        AContext.Data.Free;
        AContext.Data := nil; // <-- important
    end;

    procedure TMainForm.IdTCPServer1Execute(AContext: TIdContext);
    var
        Param: Integer;
        Data: string;
    begin
        Data := AContext.Connection.IOHandler.ReadLn;
        Param := StrToInt(Copy(Data, 1, 2));
        Delete(Data, 1, 2);

        case Param of
            10: Log('Client is version: ' + Data);
            11:
                begin
                    TMyData(AContext.Data).Username := Data;
                    Log('Client Username is: ' + Data);
                end;
            12:
                begin
                    TMyData(AContext.Data).Password := Data;
                    Log('Client Password is: ' + Data);
                end;
            99: Log(TMyData(AContext.Data).Username + ' - Client sends
message: ' + Data);
        end;
    end;


Alternatively, you can derive a new class from TIdContext, and then assign
it to the server's ContextClass before activating the server, ie:

    type
        TMyContext = class(TIdContext)
        public
            UserName: String;
            Password: String;
        end;

    constructor TMainForm.Create(AOwner: TComponent);
    begin
        inherited Create(AOwner);
        IdTCPServer1.ContextClass := TMyContext;
        //...
    end;

    procedure TMainForm.IdTCPServer1Execute(AContext: TIdContext);
    var
        Param: Integer;
        Data: string;
    begin
        Data := AContext.Connection.IOHandler.ReadLn;
        Param := StrToInt(Copy(Data, 1, 2));
        Delete(Data, 1, 2);

        case Param of
            10: Log('Client is version: ' + Data);
            11:
                begin
                    TMyContext(AContext).Username := Data;
                    Log('Client Username is: ' + Data);
                end;
            12:
                begin
                    TMyContext(AContext).Password := Data;
                    Log('Client Password is: ' + Data);
                end;
            99: Log(TMyContext(AContext).Username + ' - Client sends
message: ' + Data);
        end;
    end;


Gambit

Replies:

none

In response to:

www.cryer.info
Managed Newsgroup Archive