Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Mar : Re: How to set the listen port for the TIdTCPServer?

www.cryer.info
Managed Newsgroup Archive

Re: How to set the listen port for the TIdTCPServer?

Subject:Re: How to set the listen port for the TIdTCPServer?
Posted by:"Remy Lebeau (TeamB)" (no.spam@no.spam.com)
Date:Sun, 25 Mar 2007 15:38:20

"Bo Berglund" <bo.berglund@telia.com> wrote in message
news:5jrd035l3e93che03n679pnl8ibpg0g2ct@4ax.com...

>   while not AThread.Terminated and AThread.Connection.Connected do

Get rid of that line.  You should not be looping at all.  TIdTCPServer
triggers the OnExecute event handler inside an internal loop of its
own.

> It seems like the server is stripping off the terminator (</msg>
> from the returned data.

It is.  That is how ReadLn() is designed to operate

> Could this be changed so that I will receive the complete string?

The simpliest way is to append the terminator to the end of the data
that is returned, ie:

    procedure TTool.srvCommandExecute(AThread: TIdPeerThread);
    var
        sRecData: String;
    begin
        sRecData := AThread.Connection.ReadLn('</msg>', 2000);
        if sRecData <> '' then
            AddCmdResponse(sRecData + '</msg>');
    end;

Alternatively, I normally would suggest using WaitFor() instead of
ReadLn(), ie:

    procedure TTool.srvCommandExecute(AThread: TIdPeerThread);
    var
        sRecData: string;
    begin
        sRecData := AThread.Connection.WaitFor('</msg>');
        AddCmdResponse(sRecData);
    end;

However, WaitFor() is buggy in Indy 9.  If there is pending data in
the socket after the desired message, the extra data gets included in
the result, which will mess up your communication.  This was fixed in
Indy 10, ie:

    procedure TTool.srvCommandExecute(AContext: TIdContext);
    var
        sRecData: string;
    begin
        sRecData := AThread.Connection.IOHandler.WaitFor('</msg>',
True, True);
        AddCmdResponse(sRecData);
    end;

But for Indy 9, you would have to call ReadFromStack() and then
manually scan the InputBuffer, ie:

    procedure TTool.srvCommandExecute(AThread: TIdPeerThread);
    var
        sRecData: String;
        iPos: Integer;
    begin
        repeat
            AThread.Connection.ReadFromStack(True, 100, False);
            iPos := MemoryPos('</msg>',
PChar(AThread.Connection.InputBuffer.Memory),
AThread.Connection.InputBuffer.Size);
        until iPos <> 0;
        sRecData := AThread.Connection.ReadString(iPos+5);
        AddCmdResponse(sRecData);
    end;


Gambit

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive