예제 #1
0
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;
}
예제 #2
0
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;
}