TSocket timeout

I noticed TSocket::Recv hangs indefinitely when there is nothing on the socket to read. Is there a way to set a timeout?

Thanks.

Kevin

Hi Kevin,

For recent ROOT versions (>=4.02.00) you can use TSocket::Select to test if a read would block within a given timeout.

TSocket *s = new TSocket(...);
Long_t timeout = 1000; // in millisec
Int_t rc = -1;
if ((rc = s->Select(TSocket::kRead,timeout)) > 0) {
   s->Recv(...);
} else if (rc == 0) {
   // timeout
} else {
   // error
}

For previous versions you should be able to do the same adding the socket to a TMonitor and using TMonitor::Select to test when a read would not block.

Hope it helps.

Gerri Ganis

Gerri, thanks for the info on TSocket::Select.

A related question: I noticed sometimes sockets hang in their constructor when the destination address is not accepting connections. Is their a way to set a timeout for this as well? Thanks.

Kevin

Hi Kevin,

The connection timeout is a system parameter which cannot be changed on the fly. However you can simulate a timeout using a TTimer. Something like this:

Add a method to your class to handle the timeout

class MyClass {

    Bool_t          fTimeOut;   // to flag timeouts
    ...
public:
   void               HandleTimeOut();
    ...
};

The method could be just something like this:


void MyClass::HandleTimeOut()
{
   // Called in connection with a timer timeout

   Info("HandleTimeOut", "timeout expired");

   // Flag it
   fTimeOut = 1;

   return;
}

In your code, create a TTimer just before attempting connection, and connect it to HandleTimeout


     TTimer alarm(0, kFALSE);

     //  kernel should not restart interrupt syscalls
     alarm.SetInterruptSyscalls();

     // The method HandleTimeOut will be called at timeout
     alarm.Connect("Timeout()", "MyClass", this, "HandleTimeOut()");

and then start the timeout before attempting the connection

      // reset fTimeOut
      fTimeOut = 0;

      // Start timeout of 5 secs; the second argument indicates that
      // we want one-shot only
      alarm.Start(5000, kTRUE);

      TSocket *s = new TSocket("<host>",<port>);

      if (fTimeOut) {
           // time out
      }

If opening the connection hangs, after 5 secs HandleTimeOut is called and execution continued just after the blocking call. You can use fTimeOut to find out whether it timed out or not.

Hope it helps.

Gerri

Hello,
I have met the same problem (no server == long hang at TSocket).

{ alarm.Start(5000, kTRUE); TSocket *s = new TSocket(host,port); if (fTimeOut) { // time out }
This code doesnot interrupt the TSocket, right? It just gives you a message that it was too long? The same what I could achieve using timestamp…?
Is there any mean how to make the hang 10 seconds long instead of 120+ ? Or kill TSocket somehow (I manage to get into HandleTimeOut() function after my timeout…)
thanks,
Jaromir