tags:

views:

225

answers:

2

I have developed a Delphi web server application (TWebModule). It runs as a ISAPI DLL on Apache under Windows. The application in turn makes frequent https calls to other web sites using the Indy TIdHTTP component. Periodically I get this error when using the TIdHTTP.get method:

Could not bind socket. Address and port are already in use

Here is the code:

  IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
  IdHTTP := TIdHTTP.create(nil);


  idhttp.handleredirects := True;
  idhttp.OnRedirect := DoRedirect;
  with IdSSLIOHandlerSocket1 do begin
    SSLOptions.Method := sslvSSLv3;
    SSLOptions.Mode :=  sslmUnassigned;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 2;
  end;
  with IdHTTP do begin
    IOHandler := IdSSLIOHandlerSocket1;
    ProxyParams.BasicAuthentication := False;
    Request.UserAgent := 'Test Google Analytics Interface';
    Request.ContentType := 'text/html';
    request.connection := 'keep-alive';
    Request.Accept := 'text/html, */*';
  end;
  try
    idhttp.get('http://www.mysite.com......');
  except
    .......
  end;
  IdHTTP.free;
  IdSSLIOHandlerSocket1.free;

I have read about the reusesocket method, which can be set on both the TIdHttp and TIdSSLLIOHandlerSocketOpenSSL objects. Will setting this to rsTrue solve my problems? I ask because I have not been able to replicate this error, it just happens periodically.

Other considerations:

  • I know multiple instances of TWebModule are being spawned.
  • Would wrapping all calls to TIdHttp.get within a TCriticalSection solve the problem?

UPDATE: After doing more searching on the internet I came across this: link text

When I do a netstat -n I too get a bunch of entries with status "CLOSE_WAIT".

+1  A: 

Try to allocate a high port number. Hooking low (0..1023) ports requires admin rights IIRC.

Forget it, my bad. tidhttp is the client, not the server.

Yes, it sounds like multiple threads try to use the same tidhttp.

A cricial section would work, but effectively serialize the result. If that is a problem, use a pool of tidhttp clients.

Marco van de Voort
You mean use a static port on the idhttp component? Is there a chance that some other function is occurring on the server which might cause a conflict on this port?
M Schenkel
OK - I will give this a try. So if I understand correctly; simultaneous calls with the TIdHttp over the same port are not allowed. There can be only one call at a time. What perplexes me though, is that once this error occurs it continues for all subsequent calls (even though I am quite sure they are not occurring concurrently with other calls). It's like once it breaks once it is broken for good.
M Schenkel
Question: Do I need to create my own "management" for the pool of tidhttp clients?
M Schenkel
This happened to occur again. While the Apache Webserver was still running in this erroneous state I did a netstat. All of the lines were marked CLOSE_WAIT. When I restarted Apache many of these changed to TIME_WAIT. I know very little about this but will proceed to read up on it. From what I can gather I may not be explicitly closing my tcp/ip connections from the Indy component.
M Schenkel
A: 

I actually finally figured this out. Turns out I was NOT freeing the TIDHttp object. In my prototype example it shows it is. But my actual source code uses objects and the code where the idhttp object is freed is contained in a destructor not properly marked with override. So it was never called.

M Schenkel