gpt4 book ai didi

c - 非阻塞 connect() 和 EINTR

转载 作者:太空宇宙 更新时间:2023-11-04 02:58:17 30 4
gpt4 key购买 nike

我正在使用来自 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() 的返回码(和 errno)?

目前,当连接到一个不存在的主机并且信号中断 select() 时,此函数会错误地返回成功。

最佳答案

我不确定 Select() 是什么。我假设它是 select() 的某种薄包装器。

在大多数应用程序中,每当 select()EINTR 而失败时,您应该静默循环并再次调用 select(),可能是在重新计算之后超时以说明在之前调用 select() 时已经过去了一段时间这一事实。

这次也不异常(exception)。 select() 应该在循环中。

关于c - 非阻塞 connect() 和 EINTR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14983335/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com