套接字超时:它有效,但为什么以及如何,主要是select()函数?
这是我现在使用的代码的一部分。
fd_set fdset; struct timeval tv; int flags = fcntl(sockfd, F_GETFL); fcntl(sockfd, F_SETFL, O_NONBLOCK); connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); FD_ZERO(&fdset); FD_SET(sockfd, &fdset); tv.tv_sec = 3; tv.tv_usec = 0; if (select(sockfd + 1, NULL, &fdset, NULL, &tv) == 1) { int so_error; socklen_t len = sizeof so_error; getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len); if (so_error == 0) { cout << " - CONNECTION ESTABLISHED\n"; } } else { cout << " - TIMEOUT\n"; exit(-1); }
我不清楚select()函数是如何工作的,这里伪代码是我真正想要做的,
bool showOnce = true; connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) while(stillConnecting) /*Some kind of flag of connection status*/ { if(showOnce) { showOnce = false; cout << "Connecting"; } } if(connected) /*Another possible flag if it exists*/ return true; else return false;
反正有没有实现这个伪代码,这些标志存在吗?
编辑:为什么在上面的代码中的select函数中sockfd + 1? 为什么要添加一个?
阅读手册: man 2 select
:
-
nfds is the highest-numbered file descriptor in any of the three sets, plus 1.
,这就是sockfd + 1
的原因。 -
select()
返回触发请求事件的描述符数。 只给出了一个描述符,因此select最多可以返回1
。 - 因此,如果3秒后,给定的超时,没有任何反应,
select()
不返回1
,所以你认为它是超时。 不处理错误-1
的情况。