使用alarm()是唯一在unix域套接字上设置connect()超时的吗?我已经尝试了select(),它描述了here,但似乎select()每次都在unix域套接字上立即返回ok并且通过调用getsockopt(SO_ERROR)没有发生错误,但是fd上的send()返回错误说Transport endpoint is not connected
。我粘贴下面的select()代码。
我认为使用闹钟会遇到这种情况,但似乎它被认为是一种古老的方式。所以我在这里看看是否还有其他解决方案。提前致谢。
if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
syslog(LOG_USER|LOG_ERR, "fcntl get failed: %s", strerror(errno));
close(fd);
return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
syslog(LOG_USER|LOG_ERR, "set fd nonblocking failed: %s", strerror(errno));
close(fd);
return -1;
}
if(connect(fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINPROGRESS) {
close(fd);
return -1;
}
FD_ZERO(&set);
FD_SET(fd, &set);
if(select(fd + 1, NULL, &set, NULL, &timeout) <= 0) {
close(fd);
return -1;
}
/*
if(connect(fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
close(fd);
return -1;
}
*/
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) < 0) {
syslog(LOG_USER|LOG_ERR, "getsockopt failed: %s", strerror(errno));
close(fd);
return -1;
}
if(error != 0) {
syslog(LOG_USER|LOG_ERR, "getsockopt return error: %d", error);
close(fd);
return -1;
}
}
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) {
syslog(LOG_USER|LOG_ERR, "set fd blocking failed: %s", strerror(errno));
close(fd);
return -1;
}
在另一篇文章的某处(我没有将该页面加入书签)我发现connect()
只建立了一个TCP连接。它只意味着在另一端,有一个工作的TCP堆栈,但这并不意味着,服务器实际上有accept()
-ed!
connect()
的例子就像打电话给支持中心,自动语音告诉你,你在排队,但你还是无法沟通。 accept()
是接听电话的实际运营商。
我对同一问题的解决方案是让客户端等待服务器实际发送一些内容,然后继续使用其他客户端内容。我可以把它放在select-timeout循环中。
listen()
有一个参数,在开始删除客户端连接尝试之前,可以在待办事项中放入多少个连接。