Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Non-blocking TCP always returns Error when trying to connect to server (Windows)  (Read 10810 times)

0 Members and 1 Guest are viewing this topic.

Marukyu

  • Newbie
  • *
  • Posts: 36
    • View Profile
Hello,

first off, my apologies for bothering with pretty much the same issue as last time again. I have been trying to compile my project for Windows, and everything is working flawlessly except for the client's TCP socket. Using a similar code setup as described in the previous thread about a related uncertainity, upon trying to connect, the non-Blocking TcpSocket first returns "NotReady" (as expected), but any subsequent calls to connect() result in "Error" being returned. The server can see the client connecting, but as soon as "connect()" is called client-side a second time, it seems to disconnect again. The following code example that resembles the one linked to before reproduces the issue for me: connecting to a valid server with a non-blocking TCP socket prints "Socket not ready" once and then enters an infinite loop of "Socket error":

Code: [Select]
int main()
{
    sf::TcpSocket netTCP;
    netTCP.setBlocking(false);
    while(true)
    {
        switch (netTCP.connect("localhost", 8989, sf::Time::Zero))
        {
        case sf::Socket::Done:
            std::cout << "Connection successful" << std::endl;
            return 0;    // success.
        case sf::Socket::Disconnected:
            std::cout << "Connection refused" << std::endl;
            break;
        case sf::Socket::Error:
            std::cout << "Socket error" << std::endl;
            break;
        case sf::Socket::NotReady:
            std::cout << "Socket not ready" << std::endl;
            break;
        default:
            std::cout << "Unknown Error" << std::endl;
            break;
        }
    }
}

Firewall exceptions and stuff are set up correctly, and the server can see the client connecting for a short moment, so it is probably a client-side problem. The same code works flawlessly on Linux.

Any help or information on what I might doing wrong here would be greatly appreciated.

Marukyu

  • Newbie
  • *
  • Posts: 36
    • View Profile
Sorry for double-posting here, I am not so sure what the rules on this forum are concerning that, but I really can't figure out what is wrong with my code, and this is kind of hindering the development/testing progress of what I'm currently working on.

I have checked out the SFML source code, and there are lots of possible causes for the sf::Socket::Error return value, so I couldn't really figure out the exact reason for why this error is occuring. Does anyone else here constantly get this problem when trying to work with non-blocking TCP sockets; i.e. is it a bug in SFML's Winsock implementation, a mistake in my code or just my Windows acting up?
A possible workaround for this is to set the socket as blocking when connecting, and then switch to non-blocking mode when sending/receiving. This only functions as a temporary workaround though, as it will lock up the application during the process of connecting, unless a thread is used. Besides, if it actually isn't just an anomaly on my system, it is probably supposed to work as the developer would expect it to rather than having to use a workaround like that.

TL;DR: Am I the only one having being unable to use connect() on non-blocking TCP sockets on Windows?
« Last Edit: April 01, 2012, 08:10:48 pm by def8x »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
As far as I know, only few people use Connect in non-blocking mode, so it hasn't been widely tested and a bug in the implementation is possible.

I'd need to do some tests, but I don't have much time available, sorry.

Have you tried to use a non-zero timeout?

Quote
Sorry for double-posting here, I am not so sure what the rules on this forum are concerning that
There's no rule, you can post as long as you have something relevant to say ;)
Laurent Gomila - SFML developer

Marukyu

  • Newbie
  • *
  • Posts: 36
    • View Profile
Thanks for your response! ^^

I've been messing around with the timeout, and it didn't seem to have any effect.

I would love to help with testing/fixing this, but unfortunately I have no idea how WinSock works, and actually I'm not even sure what part of the code is causing the error, as "sf::Socket::Error" catches pretty much any kinds of implementation errors as well as various "higher-level" errors that can occur at all.
« Last Edit: April 01, 2012, 09:16:36 pm by def8x »

Marukyu

  • Newbie
  • *
  • Posts: 36
    • View Profile
Alright, I've nailed down the error to WSAGetLastError-code 10056, which is "socket is already connected". So I guess the Unix-like approach isn't quite applicable to Windows and connect() does not work as a polling function for non-blocking TCP sockets. Despite my knowledge about Winsock being virtually zero, I guess some research on how to properly deal with non-blocking TCP sockets couldn't hurt.

I will update this post once I find a possible solution.

EDIT:
Aaaaand already found something that looks very promising:
According to MSDN, you have to use the select() function to poll whether a non-blocking socket has successfully connected/is writable. It seems all you have to do is replace the connect() function with select() when working with a connecting non-blocking TCP socket on Windows. This will probably require some restructuring of the platform-independant part of the SFML socket code though, as you'll have to know when the socket is trying to "re-connect" to choose between calling connect() and select()...

EDEDITIT:
Actually, another approach would be to replace the current poll-ish system for the TcpSocket::connect() function with a single call to TcpSocket::connect() and then subsequent calls to TcpSocket::isReady() or something like that, just for non-blocking sockets. The Unix version of that code could maybe store the previous return codes to "remember" if it's ready or not. These are just my suggestions on how to possibly implement this, it's still up to you to decide if/how you are going to solve this issue.
« Last Edit: April 02, 2012, 02:32:40 pm by def8x »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Thanks for your help. I definitely need to test and fix non-blocking connect.

I'll add an issue to the bug tracker so that I don't forget it :)
Laurent Gomila - SFML developer

Marukyu

  • Newbie
  • *
  • Posts: 36
    • View Profile
No problem, I'm really glad I could help improve this great library! :)
Good luck with debugging the code, and keep up the great work!