bool SocketConnection::_createSocket()
{
    ConstConnectionDescriptionPtr description = getDescription();
#ifdef _WIN32
    const DWORD flags = WSA_FLAG_OVERLAPPED;
    const SOCKET fd = WSASocketW( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0,
                                  flags );
#else
    const Socket fd = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
#endif

    if( fd == INVALID_SOCKET )
    {
        LBERROR << "Could not create socket: "
                << lunchbox::sysError << std::endl;
        return false;
    }

    _tuneSocket( fd );

    _readFD  = fd;
    _writeFD = fd; // TCP/IP sockets are bidirectional

    return true;
}
bool SocketConnection::_createSocket()
{
    ConstConnectionDescriptionPtr description = getDescription();
#ifdef _WIN32
    const DWORD flags = description->type == CONNECTIONTYPE_SDP ?
                            WSA_FLAG_OVERLAPPED | WSA_FLAG_SDP :
                            WSA_FLAG_OVERLAPPED;

    const SOCKET fd = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0,0,flags );

    if( description->type == CONNECTIONTYPE_SDP )
        LBINFO << "Created SDP socket" << std::endl;
#else
    Socket fd;
    if( description->type == CONNECTIONTYPE_SDP )
        fd = ::socket( AF_INET_SDP, SOCK_STREAM, IPPROTO_TCP );
    else
        fd = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
#endif

    if( fd == INVALID_SOCKET )
    {
        LBERROR << "Could not create socket: "
                << lunchbox::sysError << std::endl;
        return false;
    }

    _tuneSocket( fd );

    _readFD  = fd;
    _writeFD = fd; // TCP/IP sockets are bidirectional


    return true;
}
ConnectionPtr SocketConnection::acceptSync()
{
    LB_TS_THREAD( _recvThread );
    if( !isListening( ))
        return 0;

    LBASSERT( _overlappedAcceptData );
    LBASSERT( _overlappedSocket != INVALID_SOCKET );
    if( _overlappedSocket == INVALID_SOCKET )
        return 0;

    // complete accept
    DWORD got   = 0;
    DWORD flags = 0;

    if( !WSAGetOverlappedResult( _readFD, &_overlappedRead, &got, TRUE,
                                 &flags ))
    {
        LBWARN << "Accept completion failed: " << lunchbox::sysError
               << ", closing socket" << std::endl;
        close();
        return 0;
    }

    sockaddr_in* local     = 0;
    sockaddr_in* remote    = 0;
    int          localLen  = 0;
    int          remoteLen = 0;
    GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16,
                          sizeof( sockaddr_in ) + 16, (sockaddr**)&local,
                          &localLen, (sockaddr**)&remote, &remoteLen );
    _tuneSocket( _overlappedSocket );

    ConstConnectionDescriptionPtr description = getDescription();
    SocketConnection* newConnection = new SocketConnection;
    ConnectionPtr connection( newConnection ); // to keep ref-counting correct

    newConnection->_readFD  = _overlappedSocket;
    newConnection->_writeFD = _overlappedSocket;

#ifndef _WIN32
    //fcntl( _overlappedSocket, F_SETFL, O_NONBLOCK );
#endif

    newConnection->_initAIORead();
    _overlappedSocket       = INVALID_SOCKET;

    newConnection->_setState( STATE_CONNECTED );
    ConnectionDescriptionPtr newDescription = newConnection->_getDescription();
    newDescription->bandwidth = description->bandwidth;
    newDescription->port = ntohs( remote->sin_port );
    newDescription->setHostname( getHostName( *remote ));

    LBDEBUG << "accepted connection from " << newDescription->getHostname()
           << ":" << newDescription->port << std::endl;
    return connection;
}
ConnectionPtr SocketConnection::acceptSync()
{
    if( !isListening( ))
        return 0;

    sockaddr_in newAddress;
    socklen_t   newAddressLen = sizeof( newAddress );

    Socket    fd;
    unsigned  nTries = 1000;
    do
        fd = ::accept( _readFD, (sockaddr*)&newAddress, &newAddressLen );
    while( fd == INVALID_SOCKET && errno == EINTR && --nTries );

    if( fd == INVALID_SOCKET )
    {
      LBWARN << "accept failed: " << lunchbox::sysError << std::endl;
        return 0;
    }

    _tuneSocket( fd );

    ConstConnectionDescriptionPtr description = getDescription();
    SocketConnection* newConnection = new SocketConnection;

    newConnection->_readFD      = fd;
    newConnection->_writeFD     = fd;
    newConnection->_setState( STATE_CONNECTED );
    ConnectionDescriptionPtr newDescription = newConnection->_getDescription();
    newDescription->bandwidth = description->bandwidth;
    newDescription->port = ntohs( newAddress.sin_port );
    newDescription->setHostname( inet_ntoa( newAddress.sin_addr ));

    LBDEBUG << "Accepted " << newDescription->toString() << std::endl;
    return newConnection;
}