Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Indy10 IdMappedPortTCP flawed!

269 views
Skip to first unread message

PD

unread,
Aug 4, 2006, 8:58:05 AM8/4/06
to
Hi all Indy team, hi again Remy,

After having nerded around in the indy code trying to reveal the flaw
in IdMappingPortTCP I have found the following that MIGHT
be of interest (see further below)..

First to the problem:
I have a setup in Delphi2006. A simple form, an IdMappedPortTCP
and two buttons: one to start and one to stop port mapping.

The IdMappedPortTCP has been setup as follows:

DefaultPort = 3051
MappedHost = ''192.168.2.2''
MappedPort = 3050

When connecting from IBExpert to a Firebird database through the
port mapper, the communication between the client and the server
suddently and "unexplanably" hangs after having worked for a
short time, i.e. some data are being transferred before the
mapper stops working.

The stop is not being detected as a "connection lost" by
neither client nor server.

Thats the nearest I can explain the flaw. If you have any particular and
precise description of what extra info you might need to track down
the problem please feel free to ask. I will be more than happy to
help if I can.

After "batteling" a little with the Indy code myself I tried to add the
following line in the unit IDStackWindows (around line 860).

//***********************
function TIdSocketListWindows.SelectReadList(var VSocketList: TIdSocketList;
const ATimeout: Integer): Boolean;
var
LSet: TFDSet;
begin
// Windows updates this structure on return, so we need to copy it each
time we need it
GetFDSet(LSet);

sleep(10); { <== This line is Extra added to make it (more) stable}

FDSelect(@LSet, nil, nil, ATimeout); { <== This is where the app will
just
hang for a period of ATimeout without fetching any data once the
dataflow stops}

Result := LSet.fd_count > 0;
if Result then begin
if VSocketList = nil then begin
VSocketList := TIdSocketList.CreateSocketList;
end;
TIdSocketListWindows(VSocketList).SetFDSet(LSet);
end;
end;

//***********************

Whereas the mapper would surely crash at the first or second connect
attempt before I did this modification, I have now successfully done
around 40 connects/disconnects from the firebird database using
IB-Expert through the mapper before the data flow stops again inside
the IdMappedPortTCP. Not stable, but better.

I doubt that the call to the sleep function itself has anything to do with
it, but maybe there is a sync sensitive operation (maybe an unreleased mutex
or a missing mutex) somewhere in the Indy code? (just an idea).

I tried this out both on a "bamboo" AMD Athlon 2000 plus running Win2000
and on a HP dual processor AMD Opteron machine running Win2003
terminal server, both with the same results.

As I have mentioned in an earlier thread, Indy 9 with the exact same
setup doesn't suffer from the problem and an application serving around
1000 users each day, all connecting through an Indy 9 port mapper,
has been working flawlessly for years.

I hope this can give inspiration to finding out what is wrong. I have
searched the news groups, and I can see that this error in the
IdMappedPortTCP has been mentioned several times - each time rejected with
the argument that there is not enough specification of what goes wrong. At
least I have pointed out now a place inside the Indy code that actually has
some impact on the problem, though not at all solving it. But bright brains
that know the Indy code might be able to use it as a hint.

The datastream that is sent through the mapper is from all the ASCII
spectre, from #0 to #255. I have learned from other postings regarding the
exact same problem that normal text based traffic seems to pass through
without problems.
(reference:
http://groups.google.dk/group/borland.public.delphi.internet.winsock/browse_thread/thread/1c2bdff477cec725/8409c64bfbb05fe8?lnk=st&q=&rnum=9&hl=da#8409c64bfbb05fe8 )

Maybe that knowledge will add to the problem solving a well.

Now you have my code - it would be great if you try it out, even if testing
Indy10 means that you actually have to install Indy10. Maybe you will have a
better understanding for the problem once the app hangs. If you put just a
little stress on it I am sure it will hang for you :(

It is a pity that the exact same issue has come up before - without being
solved. Maybe even without being looked into by the developers. But I think
that as an Indy developer you could have some interest and pride in taking
the problem seriously enough to try it out yourself. Indy is a great suite,
but it is very sad that people start using other component suites because
of this particular issue.

Please try it out!


Kind regards
Poul Dige

My project code (Delphi 2006) is very very simple.
It looks like this (the form definition is first, then comes the unit code):

************************************************
object Form3: TForm3
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 228
ClientWidth = 378
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 32
Top = 80
Width = 75
Height = 25
Caption = 'Start'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 113
Top = 80
Width = 75
Height = 25
Caption = 'stop'
TabOrder = 1
OnClick = Button2Click
end
object IdMappedPortTCP1: TIdMappedPortTCP
Bindings = <>
DefaultPort = 3051
ListenQueue = 100
TerminateWaitTime = 0
MappedHost = ''192.168.2.2''
MappedPort = 3050
Left = 64
Top = 24
end
end


************************************************


unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdMappedPortTCP, IdBaseComponent, IdComponent,
IdCustomTCPServer;

type
TForm3 = class(TForm)
IdMappedPortTCP1: TIdMappedPortTCP;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
IdMappedPortTCP1.Active := true;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
IdMappedPortTCP1.Active := false;
end;

end.

************************************************


Jamie Dale

unread,
Aug 4, 2006, 9:48:25 AM8/4/06
to
G'day

So will this fix the problem for HTTP traffic? (If you try the demo from the
atozed website it will work on local lans but not on the internet for some
really strange reason).

Good to see someone has been trying to fix this!

-Jamie

"PD" <p...@DoNotSpam.tabulex.dk> wrote in message
news:44d3...@newsgroups.borland.com...

PD

unread,
Aug 4, 2006, 10:27:17 AM8/4/06
to
Jamie,

No fix, unfortunately. This is just an observation that might help the Indy
developers locate what might is wrong. Something IS wrong.

I have seen an earlier description stating that text based traffic would be
routed okay but that non text based traffic would hang the mapper (see the
link towards the end of my original mail). However, I have never tried the
pure text based stuff out myself.

Kind regards
Poul

"Jamie Dale" <j.d...@turboz.net> skrev i en meddelelse
news:44d3...@newsgroups.borland.com...

Remy Lebeau (TeamB)

unread,
Aug 4, 2006, 1:15:16 PM8/4/06
to

"PD" <p...@DoNotSpam.tabulex.dk> wrote in message
news:44d3...@newsgroups.borland.com...

> I have seen an earlier description stating that text based traffic would


> be routed okay but that non text based traffic would hang the mapper

I seriously doubt that. TIdMappedPortTCP has no concept of the kind of data
that it is forwarding. TCP is just a stream of Bytes, afterall. The mapper
reads whatever is available one one socket and forwards it to the other
socket. With that said, however, Indy 9 TIdMappedPortTCP does read inbound
data as a String, and then forwards it a String. Indy 10 TIdMappedPortTCP,
on the other hand, forwards the raw bytes as-is instead.


Gambit

Remy Lebeau (TeamB)

unread,
Aug 4, 2006, 1:29:53 PM8/4/06
to

"PD" <p...@DoNotSpam.tabulex.dk> wrote in message
news:44d3...@newsgroups.borland.com...

> After "batteling" a little with the Indy code myself I tried to add


> the following line in the unit IDStackWindows (around line 860).

I have seen people report hangups in the WinSock API select() function
(which is what TIdSocketListWindows.SelectReadList() calls internally) under
various updates to Windows 2000 over the past year. Which makes this an OS
issue, not an Indy issue.


Gambit


Jamie Dale

unread,
Aug 4, 2006, 3:20:06 PM8/4/06
to
"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message

Remy,
Don't take offence at this, but thats an Indy issue - Not a
users/programmers problem.

If Indy claims to do socket work then it should do it. It shouldn't be
passed off as faulty because Indy cannot keep up with M$ updates which in
the real world, many programmers do.

While there may be OS differences, yes I agree that is down to M$. The clear
point here though, is that Indy have not kept up to date and dealt with the
issue.

Jamie


Remy Lebeau (TeamB)

unread,
Aug 4, 2006, 4:33:43 PM8/4/06
to

"Jamie Dale" <j.d...@turboz.net> wrote in message
news:44d3...@newsgroups.borland.com...

> If Indy claims to do socket work then it should do it.

It does. If the socket API itself fails to operate properly, then that is
not Indy's fault.

> It shouldn't be passed off as faulty because Indy cannot keep up
> with M$ updates which in the real world, many programmers do.

It is a Microsoft problem. I have seen people report the problem in
non-Indy projects as well. The select() function, which is very commonly
used in socket programming, can freeze up.

> While there may be OS differences, yes I agree that is down to M$.
> The clear point here though, is that Indy have not kept up to date and
> dealt with the issue.

What do you expect Indy to do about that? There is no "update" that Indy
can implement for a frozen OS function. Microsoft needs to fix heir own
stuff.


Gambit


PD

unread,
Aug 4, 2006, 5:18:16 PM8/4/06
to
Well, first of all: NICE that it is finally recognized that there is a
problem which has been known for more than a year now.

> What do you expect Indy to do about that? There is no "update" that Indy
> can implement for a frozen OS function. Microsoft needs to fix heir own
> stuff.

If M$ can't do it properly, then maybe Indy should consider to implement a
Indy9-like workaround till M$ gets the problem solved. This part of Indy is
USELESS - and has been so for a very long time - as long as it doesn't work,
no matter who's fault it is :(

Maybe it is possible to implement a proprietary Indy-Select()-function? Or
is it so integrated into the OS that we can't?

Kind regards
Poul

>
>
> Gambit
>
>


Remy Lebeau (TeamB)

unread,
Aug 4, 2006, 7:10:12 PM8/4/06
to

"PD" <p...@tabulex.dk> wrote in message
news:44d3...@newsgroups.borland.com...

> Maybe it is possible to implement a proprietary Indy-Select()-function?


> Or is it so integrated into the OS that we can't?

select() is a very core function in the socket API. It returns state
information about the socket that the application cannot access directly.


Gambit


0 new messages