Я использую connect_nonb() от программирования Stevens, UNIX Network:Неблокирующая подключения() и EINTR
int
connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
int flags, n, error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;
flags = Fcntl(sockfd, F_GETFL, 0);
Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
error = 0;
if ((n = connect(sockfd, saptr, salen)) < 0)
if (errno != EINPROGRESS)
return(-1);
/* Do whatever we want while the connect is taking place. */
if (n == 0)
goto done; /* connect completed immediately */
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;
if ((n = Select(sockfd+1, &rset, &wset, NULL,
nsec ? &tval : NULL)) == 0) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return(-1);
}
if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return(-1); /* Solaris pending error */
} else
err_quit("select error: sockfd not set");
done:
Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
if (error) {
close(sockfd); /* just in case */
errno = error;
return(-1);
}
return(0);
}
Эта функция позволяет пользовательский тайм-аут подключения(). Если, в то время как блокировка в select(), ожидающая завершения соединения, получает сигнал, select() выходит с -1 (EINTR). На этом этапе тайм-аут select() не истек, соединение не удалось (т. Е. Целевой хост может быть отключен), но последующий getockopt() не возвращает ошибку.
Должно ли getsockopt() возвращать ошибку или должен ли код Стивенса проверять код возврата (и errno) select()?
В настоящее время при подключении к несуществующему хосту и прерываниям сигнала select() эта функция возвращает успех неправильно.
Это, безусловно, должно проверить код возврата 'select'. Не делать этого, на мой взгляд, довольно большой надзор. –
Выберите в своем примере капитал S, что означает, что он его завернул. Что находится в завершенной версии выбора? Я бы ожидал, что он поймает и обработает EINTR там, вот что я сделаю ... – Joe
Джо, я думал, что слишком, но Select() просто добавляет печать ошибок. http://pastebin.com/Eua4vdZE – wilysloth