大家耳熟能詳的方法:
1.修改定義的宏
#undef FD_SETSIZE
#define FD_SETSIZE 1024
2.從boost asio中抽取的代碼
class win_fd_set_adapter : noncopyable{public: enum { default_fd_set_size = 1024 }; win_fd_set_adapter() : capacity_(default_fd_set_size), max_descriptor_(invalid_socket) { fd_set_ = static_cast<win_fd_set*>(::operator new( sizeof(win_fd_set) - sizeof(SOCKET) + sizeof(SOCKET) * (capacity_))); fd_set_->fd_count = 0; } ~win_fd_set_adapter() { ::operator delete(fd_set_); } void reset() { fd_set_->fd_count = 0; max_descriptor_ = invalid_socket; } bool set(socket_type descriptor) { for (u_int i = 0; i < fd_set_->fd_count; ++i) if (fd_set_->fd_array[i] == descriptor) return true; if (fd_set_->fd_count == capacity_) { u_int new_capacity = capacity_ + capacity_ / 2; win_fd_set* new_fd_set = static_cast<win_fd_set*>(::operator new( sizeof(win_fd_set) - sizeof(SOCKET) + sizeof(SOCKET) * (new_capacity))); new_fd_set->fd_count = fd_set_->fd_count; for (u_int i = 0; i < fd_set_->fd_count; ++i) new_fd_set->fd_array[i] = fd_set_->fd_array[i]; ::operator delete(fd_set_); fd_set_ = new_fd_set; capacity_ = new_capacity; } fd_set_->fd_array[fd_set_->fd_count++] = descriptor; return true; } bool is_set(socket_type descriptor) const { return !!__WSAFDIsSet(descriptor, const_cast<fd_set*>(reinterpret_cast<const fd_set*>(fd_set_))); } operator fd_set*() { return reinterpret_cast<fd_set*>(fd_set_); } socket_type max_descriptor() const { return max_descriptor_; }private: // This structure is defined to be compatible with the Windows API fd_set // structure, but without being dependent on the value of FD_SETSIZE. We use // the "struct hack" to allow the number of descriptors to be varied at // runtime. struct win_fd_set { u_int fd_count; SOCKET fd_array[1]; }; win_fd_set* fd_set_; u_int capacity_; socket_type max_descriptor_;};
使用該類替代fd_set集合,FD_SET使用該類的方法set來替換,而FD_ISSET則用is_set替代,裡面的幾個資料類型自己typedef一下,缺少的標頭檔自己加下,noncopyable是boost裡面定義的禁止拷貝類(拷貝建構函式,賦值操作為private類型,建構函式和解構函式定義為protected類型)
class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: // emphasize the following members are private noncopyable( const noncopyable& ); const noncopyable& operator=( const noncopyable& ); };
另外提一下,windows下的FD_SETSIZE指最大可以輪詢的個數,而linux的FD_SETSIZE指的是最大檔案描述符,如果輪詢的描述符大於等於該值,可能就出問題,見man:
Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior.