Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Oct : Re: TIdTrivialFTPServer and multi-homed server?
| Subject: | Re: TIdTrivialFTPServer and multi-homed server? |
| Posted by: | "Philippe Auphelle" (pauphelle.no.spam.please@wanadoo.fr) |
| Date: | Wed, 11 Oct 2006 14:26:45 |
Gambit,
>> At startup, TFTPServer only listen to the first of its bindings.
>
> Not true. It actively listens on all entries in the
> Bindings collection equally.
Weeeeeeellll...
The Indy I have is a '10.1.5' that I downloaded as a "release" early
December 2005 - I precisely checked.
And the fact is that does it just the way I said, and not the way you
thought it did:
function TIdUDPServer.GetBinding: TIdSocketHandle;
var
i: integer;
begin
if FCurrentBinding = nil then begin
if Bindings.Count < 1 then begin
Bindings.Add;
end;
for i := 0 to Bindings.Count - 1 do begin
{$IFDEF LINUX}
Bindings[i].AllocateSocket(Integer(Id_SOCK_DGRAM));
{$ELSE}
Bindings[i].AllocateSocket(Id_SOCK_DGRAM);
{$ENDIF}
Bindings[i].Bind;
end;
FCurrentBinding := Bindings[0];
FListenerThread := TIdUDPListenerThread.Create(BufferSize, Self);
FListenerThread.Start;
BroadcastEnabledChanged;
end;
Result := FCurrentBinding;
end;
As you can see,
TIdUDPListenerThread.Create(BufferSize, Self);
is called just once, with FCurrentBindings set to Bindings[0], and a
debugging session shows that this code is called only once, creating a
single thread. The call happens when I set the server active, in
TIdUDPBase.SetActive. And the TIdUDPServer object has room to keep track
of a single TIdUDPListenerThread in FListenerThread, anyway.
Bottom line: That version didn't support multi-homing, except maybe by
running several instances of the server object and passing to each a
different local address.
Ooops.
This behavior precisely matches the experimental facts I reported, BTW.
Facts are stubborn.
Now for the good news!
The latest snapshot (that I haven't tried yet, need to carefully build
and test it first) looks much better, since GetBinding does create one
listener per thread. And FListenerThread is now a TidThreadList, while
it used to be a TIdUDPListenerThread.
The code is a tad longer, but here is the excerpt that I more specially
like:
for i := 0 to Bindings.Count - 1 do begin
LListenerThread := TIdUDPListenerThread.Create(Self, Bindings[i]);
LListenerThread.Name := Name + ' Listener #' + Sys.IntToStr(i + 1);
LListenerThread.Priority := tpListener;
FListenerThreads.Add(LListenerThread);
LListenerThread.Start;
end;
Aaaaaah!
Evidence found, case closed.
Thanks for (indirectly :) ) pushing me to get to the source.
I learned a few things during that trip, starting with how to properly
handle the LocalAddresses / Bindings issue. /Ph.