>Система клиент-сервер.
>
>Сервер выключен, но клиент пытается до него достучаться.
>
>Вопрос:
>
>1. сколько времени тратит коннект на попытку соединения, если сервер выключен?
>
>2. где находится параметр времени, в течении которого connect пытается установить связь
>с сервером?
>
>Отошлите плиз к необходимому ману!
По красивому это ДОЛЖНО делаться через ioctl'ы, а еще точнее через setsockopt'ы, но, к сожалению, это не всегда и не на всех дистрах корректно работает. Классический метод с SIGALARM'ами мне не очень нравится, потому как чем меньше возни с сигналами, тем проще жить. Поэтому я использую связку неблокирующий сокет + poll :
//timeout в миллисекундах, -1 это бесконечное ожидание
int t_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen, int timeout)
{
//Переведем сокет в неблокирующий режим
int cur_flg=-1;
if ((cur_flg=fcntl(sockfd, F_GETFL))==-1)
return -1;
if (fcntl(sockfd, F_SETFL, cur_flg | O_NONBLOCK)==-1)
return -1;
//Попытка соединения
if (connect(sockfd, serv_addr, addrlen)==-1)
{
if (errno!=EINPROGRESS)
{
fcntl(sockfd, F_SETFL, cur_flg);
return -1;
}
}
//Крутим poll в течении timeout
struct pollfd ufds={sockfd, POLLOUT, 0};
int poll_ret = poll(&ufds, 1, timeout);
if (poll_ret<=0)
{
fcntl(sockfd, F_SETFL, cur_flg);
return -1;
}
if (!(ufds.revents&POLLOUT))
{
fcntl(sockfd, F_SETFL, cur_flg);
return -1;
}
//Вытаскиваем из сокета код возврата
int gso_ret = 0;
socklen_t gso_ret_len = (socklen_t)sizeof(gso_ret);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &gso_ret, &gso_ret_len)==-1)
{
fcntl(sockfd, F_SETFL, cur_flg);
return -1;
}
if (gso_ret!=0)
{
errno=gso_ret;
fcntl(sockfd, F_SETFL, cur_flg);
return -1;
}
//Вернем сокет в блокирующий режим
if (fcntl(sockfd, F_SETFL, cur_flg)==-1)
return -1;
return 0;
}