Beispiel #1
0
Socket::Status TcpSocket::Connect(const IpAddress& remoteAddress, unsigned short remotePort, Uint32 timeout)
{
    // Create the internal socket if it doesn't exist
    Create();

    // Create the remote address
    sockaddr_in address = priv::SocketImpl::CreateAddress(remoteAddress.ToInteger(), remotePort);

    if (timeout == 0)
    {
        // ----- We're not using a timeout: just try to connect -----

        // Connect the socket
        if (connect(GetHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
            return priv::SocketImpl::GetErrorStatus();

        // Connection succeeded
        return Done;
    }
    else
    {
        // ----- We're using a timeout: we'll need a few tricks to make it work -----

        // Save the previous blocking state
        bool blocking = IsBlocking();

        // Switch to non-blocking to enable our connection timeout
        if (blocking)
            SetBlocking(false);

        // Try to connect to the remote address
        if (connect(GetHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) >= 0)
        {
            // We got instantly connected! (it may no happen a lot...)
            return Done;
        }

        // Get the error status
        Status status = priv::SocketImpl::GetErrorStatus();

        // If we were in non-blocking mode, return immediatly
        if (!blocking)
            return status;

        // Otherwise, wait until something happens to our socket (success, timeout or error)
        if (status == Socket::NotReady)
        {
            // Setup the selector
            fd_set selector;
            FD_ZERO(&selector);
            FD_SET(GetHandle(), &selector);

            // Setup the timeout
            timeval time;
            time.tv_sec  = timeout / 1000;
            time.tv_usec = (timeout - time.tv_sec * 1000) * 1000;

            // Wait for something to write on our socket (which means that the connection request has returned)
            if (select(static_cast<int>(GetHandle() + 1), NULL, &selector, NULL, &time) > 0)
            {
                // At this point the connection may have been either accepted or refused.
                // To know whether it's a success or a failure, we must check the address of the connected peer
                if (GetRemoteAddress() != sf::IpAddress::None)
                {
                    // Connection accepted
                    status = Done;
                }
                else
                {
                    // Connection refused
                    status = priv::SocketImpl::GetErrorStatus();
                }
            }
            else
            {
                // Failed to connect before timeout is over
                status = priv::SocketImpl::GetErrorStatus();
            }
        }

        // Switch back to blocking mode
        SetBlocking(true);

        return status;
    }
}
Beispiel #2
0
bool operator <(const IpAddress& left, const IpAddress& right)
{
    return left.ToInteger() < right.ToInteger();
}