我目前正在使用 winsock 构建服务器。我的服务器将处理多个客户端,因此我使用 select() 函数以及读取、写入和异常集。我已经知道如果特定套接字超时, select() 返回 0 。
但是我如何识别超时的实际套接字?
顺便说一句,谁能告诉我 Some_Socket 需要发生什么才能使 FD_ISSET(Some_Socket, &Exception) 返回 true?
也许我可以使用上面的函数来检查集合中的每个套接字?
编辑:
假设我有这个例子:
int main(void){
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
for(int i = 0; i<clientcount; i++) {
FD_SET(sockets[i].Scksas, &read_mask);
FD_SET(sockets[i].Scksas, &write_mask);
FD_SET(sockets[i].Scksas, &excep_mask);
}
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else{
printf("No data within five seconds.\n");
/*
Handle timed out socket, but which one ?
*/
}
exit(EXIT_SUCCESS);
}
如何判断哪个soket超时了?
最佳答案
问题是您不能使用 select
等,因为它们的超时是针对整个集合而不是单个套接字。
有三种简单的解决方案可以找出在特定时间段内没有通信的单个套接字。
最简单的可能是为每个套接字保留一个结构,并在这个结构中有一个上次通信的时间。您定期检查所有套接字的时间,如果时间太早,则关闭连接。
另一种解决方案是在协议(protocol)中添加“保持事件状态”消息。定期在所有套接字上发送“你还活着吗”消息。如果您在一段时间内没有收到“我还活着”的回复,则连接可能会被视为失效,您可以关闭它。
为每个套接字使用单独的线程或进程。然后您可以使用
select
,因为您在集合中只有一个套接字。
关于c++ - 从一组套接字中检测超时套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14378957/