Прослушивание подключения сокета без вызова в Linux

Я запускаю код в Ubuntu Linux, он должен использовать Set и выбрать, чтобы проверить, когда прослушивающий сокет активен (то есть кто-то пытается подключиться), и позволить им подключиться, проблема заключается в выборе ВСЕГДА возвращает 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 );
                    }

как вы можете видеть, он не будет выполнять .Accept до тех пор, пока ПОСЛЕ того, как он не получит активность от выбора, но он никогда не доберется так далеко. Bind and listen call is here template void ListeningManager :: AddPort (port 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 );
}

person nekosune    schedule 02.10.2011    source источник
comment
Где ты настраиваешь m_set?   -  person Mat    schedule 02.10.2011


Ответы (1)


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

person 01d55    schedule 02.10.2011