В C предположим, что у меня есть серверное приложение. Сокет настроен правильно и привязан к локальному порту, а функция listen() вызывается без ошибок.
Код такой:
//obtain a connection.
int connection;
struct sockaddr_storage sender;
socklen_t addr_size = sizeof(sender);
if((connection=accept(sockfd, (struct sockaddr*)&sender, &addr_size))==-1)
{close(sockfd); return -1; }
if(close(sockfd)==-1){
close(connection);
return -1;
}
else
return connection;
Успешно получает дескриптор файла подключения, через который данные могут быть прочитаны клиентом.
Мое приложение требует, чтобы сервер ждал определенное время, а затем отключался и выполнял другие действия, если соединение не установлено. Далее будет принято не более одного соединения. Accept() — блокирующий системный вызов, но я хотел бы избежать блокировки.
Кажется, есть много разных способов решить эту проблему:
вопрос SE предлагает использовать select для решения этой проблемы, но выберите предназначен для одновременного мониторинга многих файловых дескрипторов и здесь кажется излишним.
Другой вопрос предлагает изменить сокет, чтобы он был неблокирующим, а затем проверить в цикле, действительно ли соединение было установлено. Это тоже сработает, но кажется не очень хорошим, потому что я хочу заблокировать - но не навсегда.
В других языках люди используют SIGALARM и команду alarm() для предотвращения блокировки, но мое приложение имеет несколько потоков, и это похоже на решение, подверженное ошибкам.
В некоторых других языках (Java?) Я думаю, что есть аргумент тайм-аута, который можно передать, чтобы принять, который выполняет это. Это было бы идеально здесь, но я не могу найти подобную функцию для сокетов в C.
Есть ли более приятный способ решить эту проблему? Кажется, что кто-то другой уже понял бы это. Если нет лучшего способа, какое из упомянутых выше решений является наиболее подходящим? Я склоняюсь к тому, чтобы сделать сокет неблокирующим, но, похоже, это вносит много лишнего мусора.
select()
... некоторое время ожидания активности одного или нескольких файловых дескрипторов. Позвонитеselect()
с тайм-аутом, и вы получите то, что хотите. - person larsks   schedule 15.11.2012select()
это именно то, что вам нужно. Оберните его небольшой функцией, и это тоже не будет выглядеть излишним. - person moooeeeep   schedule 15.11.2012