Функция select
Еще в первой версии Winsock была очень интересная возможность управления неблокируемыми сокетами. Для этого используется функция select:
int select ( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout );
Функция возвращает количество готовых к использованию дескрипторов Socket.
Теперь рассмотрим параметры этой функции:
nfds — игнорируется и служит только для совместимости с моделью сокетов Беркли;
readfds — возможность чтения (структура типа fd_set);
writefds — возможность записи (структура типа fd_set);
exceptfds — важность сообщения (структура типа fd_set);
timeout — максимальное время ожидания или null для блокирования дальнейшей работы (ожидать бесконечно).
Структура fd_set — набор сокетов, oт которых нужно ожидать разрешение на выполнение определенной операции. Например, если вам нужно дождаться прихода данных на один из двух сокетов, то вы можете сделать следующее:
добавить в набор fd_set два уже созданных сокета;
запустить функцию select и в качестве второго параметра указать набор с сокетами.
Функция select будет ожидать данные указанное время, после чего можно прочитать данные из сокета. Но данные могут прийти только на один из двух сокетов. Как узнать, на какой именно? Для начала с помощью функции FD_ISSET нужно обязательно проверить, входит ли сокет в набор.
При работе со структурой типа fd_set вам понадобятся следующие функции:
FD_ZERO — очищает набор. Прежде чем добавлять в набор новые сокеты, обязательно вызывайте эту функцию, чтобы проинициализировать набор. У этой функции только один параметр — указатель на переменную типа fd_set;
FD_SET — добавляет сокет в набор. У функции два параметра — сокет, который нужно добавить, и переменная типа fd_set, в набор которой нужно добавить сокет;
FD_CLR — удаляет сокет из набора. У этой функции два параметра — сокет, который надо удалить, и набор, из которого будет происходить удаление;
FD_ISSET — проверяет, входит ли сокет, определенный в первом параметре, в набор типа fd_set, указанный в качестве второго параметра.