В 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 за решаване на това, но select е предназначен за наблюдение на много манипулатори на файлове наведнъж и тук изглежда пресилено.
Друг въпрос предлага модифициране на сокета да бъде неблокиращ и след това проверка в цикъл дали или не беше направена връзка. Това също ще работи, но не изглежда много хубаво, защото искам да блокирам - просто не завинаги.
Изглежда, че на други езици хората използват SIGALARM и командата alarm(), за да предотвратят блокиране, но моето приложение има няколко нишки и това изглежда като податливо на грешки решение.
В някои други езици (Java?) Мисля, че има аргумент за изчакване, който може да бъде предаден за приемане, което постига това. Това би било идеално тук, но изглежда не мога да намеря подобна функция за сокети в C.
Има ли по-добър начин за справяне с това? Изглежда като нещо, което някой друг вече би разбрал. Ако няма по-добър начин, кое от горепосочените решения е най-подходящо? Склоня се към това да направя сокета неблокиращ, но изглежда, че въвежда голямо количество допълнителни гафове.
select()
...изчакване известно време за активност върху един или повече файлови дескриптори. Обадете се наselect()
с таймаут и ще получите това, което искате. - person larsks   schedule 15.11.2012select()
е точно това, от което се нуждаете. Увийте го в малка функция и също няма да изглежда прекалено. - person moooeeeep   schedule 15.11.2012