为什么FD_SET / FD_ZERO用于循环内的select()?

时间:2011-10-03 16:23:44

标签: c++ select tcp clear file-descriptor

我正在使用select函数进行套接字之间的通信。我有一个循环,我做 -

    while(!done) {

    FD_ZERO(&read_flags);
    FD_ZERO(&write_flags);
    FD_SET(comm_fd1, &read_flags);
    FD_SET(comm_fd2, &read_flags);
    FD_SET(STDIN_FILENO, &read_flags);
    FD_SET(comm_fd1, &write_flags);
    FD_SET(comm_fd2, &write_flags);
    FD_SET(STDIN_FILENO, &write_flags);

    //call select
    sel = select(comm_fd1+comm_fd2+1, &read_flags, &write_flags, (fd_set*)0, &waitd);

和客户端的不同变量相同。我从在线教程中获得了这个基本技术,并且随之而来。然后它打了我 - 为什么我每次循环时清除集合并添加文件描述符?如果它们已经添加,为什么要清除它们并再次添加?所以我尝试在此之前只执行一次,并且代码不再相同。有人可以解释原因吗?是否因为select修改了集合的内容?任何帮助和/或见解都表示赞赏。

2 个答案:

答案 0 :(得分:25)

select返回时,它已更新集以显示哪些文件描述符已准备好进行读/写/异常。所有其他标志都已清除。

重新启用在开始另一个选择之前清除的文件描述符非常重要,否则,您将不再等待这些文件描述符。

至于重新清理,它是一个很好的习惯,因为如果你需要更改文件描述符集(例如将新打开的套接字添加到读取集),你将需要清除并且每次都重建它,以便在程序状态发生变化时它是正确的。

答案 1 :(得分:5)

  

是否只是因为select修改了集合的内容?

是的,在select返回后,只有准备好的描述符留在集合中。