2011-10-02 159 views
3

我正在Ubuntu Linux上運行代碼,它應該使用Set並選擇以檢查偵聽套接字何時有活動(即有人試圖連接)並讓它們連接,是選擇ALLWAYS返回0,當我嘗試連接它只是直接連接。 但在服務器上接受從不調用,因爲select始終返回0,所以我想知道什麼可能會導致此?偵聽套接字連接,而不接受在Linux上調用

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數據包;

// 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); 
        } 

,你可以看到,它不會做了。接受後,才它從選擇了活動,但它從來沒有得到那麼遠 綁定和調用聽這裏 模板 無效ListeningManager ::添加端口(端口p_port) if(m_sockets.size()== MAX) Exception e(ESocketLimitReached); (e); }

// 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); 
} 
+0

你在哪兒設置'm_set'? – Mat

回答

4

select()需要最大的fd + 1。你給它最大的fd,未經修改。如果你在Linux而不是Windows上看到這個錯誤,這是最可能的原因。