Прослушивающий сокет подключается без подтверждения вызова в Linux - PullRequest
3 голосов
/ 02 октября 2011

Я запускаю код в Ubuntu Linux, предполагается, что он использует Set и выбирает, чтобы проверить, активен ли прослушивающий сокет (т. Е. Кто-то пытается подключиться), и разрешить им подключиться, проблема в том, что ALLWAYS возвращает 0, а когда я попробуйте подключить просто подключается сразу. но на сервере Accept никогда не вызывается, так как select всегда возвращает 0, поэтому мне интересно, что может вызвать это?

namespace SocketLib
{

const int MAX = FD_SETSIZE;

class SocketSet
{
public:
    SocketSet();
    void AddSocket( const Socket& p_sock );
    void RemoveSocket( const Socket& p_sock );

    inline int Poll( long p_time = 0 )
    {
        // this is the time value structure. It will determine how long
        // the select function will wait.
        struct timeval t = { 0, p_time * 1000 };

        // copy the set over into the activity set.
        m_activityset = m_set;

        // now run select() on the sockets.
        #ifdef WIN32
            return select( 0, &m_activityset, 0, 0, &t );
        #else
            if( m_socketdescs.size() == 0 ) return 0;
            return select( *(m_socketdescs.rbegin()), &m_activityset, 0, 0, &t );
        #endif
    }

    inline bool HasActivity( const Socket& p_sock )
    {
        return FD_ISSET( p_sock.GetSock(), &m_activityset ) != 0;
    }


protected:

    // a set representing the socket descriptors.
    fd_set m_set;

    // this set will represent all the sockets that have activity on them.
    fd_set m_activityset;

    // this is only used for linux, since select() requires the largest
    // descriptor +1 passed into it. BLAH!
    #ifndef WIN32
        std::set<sock> m_socketdescs;
    #endif
};

- это код, запускающий опрос, если он помогает

Дополнительный код:

#include <algorithm>
#include "SocketSet.h"


namespace SocketLib
{

SocketSet::SocketSet()
{
    FD_ZERO( &m_set );
    FD_ZERO( &m_activityset );
}

void SocketSet::AddSocket( const Socket& p_sock )
{
    // add the socket desc to the set
    FD_SET( p_sock.GetSock(), &m_set );

    // if linux, then record the descriptor into the vector,
    // and check if it's the largest descriptor.
    #ifndef WIN32
        m_socketdescs.insert( p_sock.GetSock() );
    #endif

}

void SocketSet::RemoveSocket( const Socket& p_sock )
{
    FD_CLR( p_sock.GetSock(), &m_set );

    #ifndef WIN32
        // remove the descriptor from the vector
        m_socketdescs.erase( p_sock.GetSock() );
    #endif

}

}   // end namespace SocketSet

также используется здесь { // определить сокет данных, который будет получать соединения от прослушивания // Розетки DataSocket datasock;

    // detect if any sockets have action on them
    int i=m_set.Poll();
    if( i > 0 )
    {
        // loop through every listening socket
        for( size_t s = 0; s < m_sockets.size(); s++ )
        {
            // check to see if the current socket has a connection waiting
            if( m_set.HasActivity( m_sockets[s] ) )
            {
                try
                {
                    // accept the connection
                    datasock = m_sockets[s].Accept();

                    // run the action function on the new data socket
                    m_manager->NewConnection( datasock );
                    }

как вы можете видеть, он не будет делать. Примите, пока ПОСЛЕ того, как он получит активность от выбора, но он никогда не заходит так далеко Привязать и прослушать вызов здесь шаблон void ListeningManager :: AddPort (порт p_port) { if (m_sockets.size () == MAX) { Исключение e (ESocketLimitReached); бросок (е); }

    // create a new socket
    ListeningSocket lsock;

    // listen on the requested port
    lsock.Listen( p_port );

    // make the socket non-blocking, so that it won't block if a
    // connection exploit is used when accepting (see Chapter 4)
    lsock.SetBlocking( false );

    // add the socket to the socket vector
    m_sockets.push_back( lsock );

    // add the socket descriptor to the set
    m_set.AddSocket( lsock );
}

1 Ответ

4 голосов
/ 03 октября 2011

select () требует наибольшее fd + 1.Вы даете ему самый большой fd, без изменений.Если вы видите эту ошибку в Linux, а не в Windows, это наиболее вероятная причина.

...