SFML community forums
General => Feature requests => Topic started by: zac on January 18, 2009, 01:22:45 am
-
Problem:
The server at whatismyip.org is sometimes not responsive or does not answer our requests (for unknown reasons, though I only do a request once, when (re)starting the program).
Possible solution/workaround:
Add a way to pass a timeout value. If the connection to the server can not be created successfully, return an invalid IP.
Since you are using the HTTP class to connect by now, I would suggest to add a timeout in the HTTP/FTP class too. It is supported by the underlying sockets, so it shouldn't be to hard to implement...
-
It's done.
Thank you for your feedback :)
-
Hey, that was really fast. Thanks.
-
Hm, it does not really seem to work:
http://www.sfml-dev.org/forum/viewtopic.php?t=933
If I remove the timeout-parameter, it works.
I think this is related to a bug I posted, but there was no answer up to now - the return values of "Connect" are wrong. When its given a timeout, Connect returns 3 instead of Socket::Done, even if the connection has been built properly.
See:
http://www.sfml-dev.org/forum/viewtopic.php?t=883
I'm currently walking through the implementation of connect, but I don't see where in the connect call this bug arises.
There is at least one little bug:
If the connection is immediately successfull (Connect with timeout), you are not resetting the Blocking Mode to "true".
This might trigger a lot of funny bugs (especially with the loopback - it is very fast and so not unlikely the connection works "immediately").
-
I've replied to both of your posts. Basically, everything works fine for me.
Regarding the potential bug in Connect, I don't remember why but at the time I implemented it, I knew it was not necessary. I should have left a comment :)
-
Yes, there is one thing I first considered a bug, which isn't, because there is an immediate return if the socket is non-blocking. But this one definitely is. If you try to connect with a blocking socket with timeout, and the connection is successfull on the first "connect" call, you will end up with a Non-Blocking socket.
Maybe this is simply not possible, connect succeeding on the first time, (who knows? I don't see any reason why it can't be possible), or it just appears on loopback or something like this...
You could replace:
bool IsBlocking = myIsBlocking;
if(IsBlocking)
SetBlocking(false);
if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0)
{
// We got instantly connected! (it may no happen a lot...)
return Socket::Done;
}
by:
bool IsBlocking = myIsBlocking;
if(IsBlocking)
SetBlocking(false);
if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0)
{
// We got instantly connected! (it may no happen a lot...)
if(IsBlocking)
SetBlocking(true);
return Socket::Done;
}
I will do some bug research with the SocketTCP connect code... I will tell you if I know more about the return value thingy.
-
I GOT it.
Please add:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
case EAGAIN: return Socket::NotReady;
#endif
#if defined(EINPROGRESS) && EINPROGRESS != EWOULDBLOCK && EINPROGRESS != EAGAIN
case EINPROGRESS: return Socket::NotReady;
#endif
to the switch-case in the Linux "SocketHelper.cpp" SocketHelper::GetErrorStatus()!
The error values are sometimes the same, but obviously not always.
connect sets errno to EINPROGRESS, in my case.
See:
http://linux.die.net/man/2/connect
The precompiler statements just make sure there are no double values in the switch case.
This also explains why it works perfectly on windows ;) ;)
Together with this one, all the other bugs vanished. Everything is working fine with these changes.
-
Ahah!
Great job, I just applied the fix :)