我有一个使用阻塞connect()调用的现有多线程应用程序。
但是,我想为应用程序引入连接超时,如果服务器在x毫秒内没有响应我们的查询,应用程序将停止尝试并给出错误。
但是,我无法弄清楚如何使用民意调查来做到这一点。
@caf使用select的非阻塞连接非常有帮助。 但是我已经阅读了与民意调查相比较慢的选择,因此我想使用民意调查。你能否告诉我这是否属实?
我从the post这里粘贴他的代码
int main(int argc, char **argv) {
u_short port; /* user specified port number */
char *addr; /* will be a pointer to the address */
struct sockaddr_in address; /* the libc network address data structure */
short int sock = -1; /* file descriptor for the network socket */
fd_set fdset;
struct timeval tv;
if (argc != 3) {
fprintf(stderr, "Usage %s <port_num> <address>\n", argv[0]);
return EXIT_FAILURE;
}
port = atoi(argv[1]);
addr = argv[2];
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(addr); /* assign the address */
address.sin_port = htons(port); /* translate int2port num */
sock = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);
connect(sock, (struct sockaddr *)&address, sizeof(address));
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 10; /* 10 second timeout */
tv.tv_usec = 0;
if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error == 0) {
printf("%s:%d is open\n", addr, port);
}
}
close(sock);
return 0;
}
你能帮我用poll编写类似的功能吗?
我在RHEL上并使用gcc 4.5.x版本。
更新:对于当前代码,一旦应用创建与服务器的连接,如何将套接字更改为阻止模式。我无法找到解除此O_NONBLOCK的方法。
更新2:fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) & ~O_NONBLOCK);
One post已指出我们可以使用上述命令执行此操作。虽然没有登录。
答案 0 :(得分:4)
如果只有少数文件描述符被轮询,则select()和poll()相对于其他依赖于系统的轮询API的性能是等效的。它们都很难缩放,但是当节目只收听几个fds时,它们可以表现得很好。
其他特定于系统的轮询API的一个优点往往是它们将关联状态推送到内核中,这样每个轮询系统调用都不需要从用户空间到内核空间的状态副本。只有少数事件,这种复制和扫描开销是微不足道的,并且这种好处不存在。
坚持使用select(),除非你需要扩展到处理数百或更多的fds。
如果您真的要处理许多fds,并且必须同时支持Linux和Solaris,请考虑使用类似libevent或libev的库来抽象出特定于内核的高效等待API。
答案 1 :(得分:-1)
select
不会慢于民意调查。但即使是这样,最小的差异也不大可能在你的申请中起作用。
为了执行非阻塞超时连接,您可以从提供此类功能的现有应用程序进行复制。 (参见例如here,了解如何做到这一点)。