我正在使用Stevens的connect_nonb(),UNIX网络编程:
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);
}
此函数允许connect()的自定义超时。如果在select()中阻塞等待连接成功,则接收到一个信号,select()以-1(EINTR)退出。此时select()超时尚未到期,连接未成功(即目标主机可能已断开连接),但后续的getsockopt()不会返回错误。
getsockopt()是否会返回错误,或者Stevens代码是否应该检查select()的返回码(和错误号)?
目前,当连接到不存在的主机并且信号中断select()时,此函数会错误地返回成功。
答案 0 :(得分:2)
我不确定Select()
是什么。我认为它是select()
周围的某种薄包装。
在大多数应用程序中,只要select()
失败并显示EINTR
,您应该静默循环并再次调用select()
,可能在重新计算超时后考虑到已经过了一段时间的事实事先致电select()
。
这种情况也不例外。 select()
应该循环播放。