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
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