Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Mar : Re: [Q] Bind to local adapter IPs (Usage of TIdHTTP/TCPClient)
| Subject: | Re: [Q] Bind to local adapter IPs (Usage of TIdHTTP/TCPClient) |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Mon, 20 Mar 2006 11:34:03 |
"Marc Wetzel" <mwse_n_o_s_p_a_m@gmx.de> wrote in message
news:441ed755$1@newsgroups.borland.com...
> And I can surf... but if I surf "to quickly" the socket will not be closed
> (but I really closed it - it is now in a so called half-open state,
because
> windows still wants to receive data, which might arrive after the FIN is
sent)
That is perfectly fine, because the half-open socket is bound to a different
adapter. When you switch adapters for the next socket, you should be able
to open it immediately, even if the previous one is still open. A socket is
identified by the IP/port combinations that it is bound to, and you are
changing those values each time.
> The options are called Boundportmin and ...max. But they seem not to
> have any effect, if BoundIP is set.
Yes, they do. However, in order for BoundPortMin/Max to be used, the
BoundPort must be set to 0, and the BoundPortMin/Max must both not be zero.
> Indy always uses BoundPortMax and does no retries.
Yes, it does retry. If you look at the source code for
TIdSocketHandle.BindPortReserved(), you will see that it loops from Max to
Min, not Min to Max. If the BoundPortMax value is the one always being
used, it is because the Max port is always the first opened port being
detected. If the Max port were not available, then the next lower port
would be attempted, and so on under the Min port is tried.
> Because, if the socket is closed (but in half-open state) you get an
> exception "Adress already in use...").
That should not be happening when you change the BoundIP property. That
error only occurs when you try to bind to the same IP/Port that was
previously bound and is still bound. In the case of using BoundPortMin/Man,
that error would be ignored internally and the next IP/Port combo would be
attempted.
> The same happens, if redirects (on a http1.0 connection) occur - indy
tries
> to reconnect (to connect to the new URL) - and bang: "Adress already in
use"
That should not be happening, especially if you are using the
BoundPortMin/Max properties correctly.
> How can I determine upfront if a socket is "half-open"
You cannot.
SO_REUSEADDR is a socket option used to allow a local IP/Port combo to be
reused for a new socket, without the "Address aleready in use" error being
reported, if a previously disconnected socket is still bound to that
IP/Port.
In Indy 9, unfortunately there is no option to enable the SO_REUSEADDR
option for client connections, without altering Indy's source code and
recompiling Indy.
In Indy 10, you can assign a TIdIOHandlerStack component to the TIdHTTP
(rather than letting TIdHTTP create its own implicit IOHandler internally)
and then use the IOHandler's OnSocketAllocated event to call the
TIdSocketHandle.SetSockOpt() method, ie:
procedure TForm1.IdIOHandlerStack1SocketAllocated(Sender: TObject);
begin
IdIOHandlerStack1.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_REUSEADDR,
Id_SO_True);
end;
Gambit