оператор = на fd_set — связь с сокетом linux

#c #select

#c #выберите

Вопрос:

Я пишу программу, которая использует select(), учитывая fd_set для чтения.
В программе я сохраняю два набора fd_set:
1. fd_set с именем DB со всеми fd, с которыми я могу иметь дело.
2. fd_set с именем toSelect — который я отправляю методу select () и обрабатываю позже, после возврата select().

Перед вызовом select() я делаю это:
toSelect = DB;
Чтобы скопировать все fd в DB в toSelect fd_set.
Поскольку моя программа работает не так хорошо (появляется сообщение «Сброс соединения одноранговым узлом»), вероятно, что-то не так с моим кодом.
Нормально ли это назначение? Если нет, то как я могу скопировать один fd_set в другой без использования operator = ?
Спасибо.

Комментарии:

1. При публикации здесь, пожалуйста, постарайтесь различать C и C — API select () является API C / POSIX.

Ответ №1:

Вместо того, чтобы делать toSelect = DB , попробуйте использовать макросы FD_ISSET и FD_SET для копирования значений из одного в другой и посмотрите, сохраняется ли проблема.

Ответ №2:

Внутренние детали fd_set, включая то, будет ли определен operator= (и пройдет ли компиляция), определены реализацией. Единственное, что обещает вам fd_set, — это интерфейс, который он предоставляет в виде макросов (или функций) FD_SET, FD_CLEAR, FD_ISSET, FD_ZERO.

Если вы хотите иметь возможность использовать operator=, вы можете написать для него свой собственный класс-оболочку.

Комментарии:

1. Что сказать? Назначение определено для всех типов данных C, включая определяемые пользователем, а в C — для всех типов POD. fd_set не имеет ничего общего с C .

2. @Neil Да, я ошибочно подумал, что это может не пройти компиляцию, но определение не делает такое утверждение правильным. Использование operator= не является частью обещанного интерфейса для fd_set.

3. Да, это так — fd_set является модулем.

4. fd_set явно не указано как POD, но из-за других требований, если оно не зависит от нестандартных расширений в вашем компиляторе C, оно должно быть POD.

5. Если fd_set бы использовалась какая-либо выделенная память, у стандартной реализации C не было бы способа освободить ее. Можно было бы попытаться сконструировать гипотетическую fd_set реализацию, используя нестандартную, но распространенную alloca , но тогда вы столкнулись бы с проблемами, потому что, пока fd_set не прекратит свое существование, допустимо продолжать использовать его после возврата вызванной FD_* функции (и на самом деле это было бы очень распространенным использованием, если вы учитываете настройку fd_set в качестве собственной функции в вашем приложении).