理解套接字编程中的select()

时间:2014-10-02 03:45:01

标签: sockets unix select

我正处于游戏场景中。服务器和客户端都通过非阻塞UDP以高速率交换消息。

(这里可能很奇怪......)遗留代码也使用select(),超时值设置为0,这意味着select()不会阻塞。 Select()在一个永远的while循环中。 select()返回一个大于0的数字,代码通过recvfrom()接收消息。如果它返回0,则以下代码不会尝试接收。

从打印输出信息中,我看到select()有时会返回1(大于0)。我很困惑,因为超时设置为0,select()有时间检查消息是否准备好从任何readfds读取?谢谢。

1 个答案:

答案 0 :(得分:1)

根据the spec

  

成功完成后,pselect()或select()函数应该   修改readfds,writefds和errorfds指向的对象   用于指示哪些文件描述符可供读取的参数,   准备写入,或者分别有待处理的错误条件,   并且应该返回所有的准备描述符的总数   输出集。对于每个小于nfds的文件描述符,   如果成功完成,则应设置相应的位   在输入上设置,并且该文件的关联条件为true   描述符。

     

如果所选描述符都没有为请求的操作做好准备,则pselect()或select()函数将阻塞,直到至少有一个请求的操作准备就绪,直到超时发生,或直到被中断为止信号。超时参数控制pselect()或select()函数在超时之前需要多长时间。如果timeout参数不是空指针,则它指定等待选择完成的最大间隔。如果指定的时间间隔到期而没有任何请求的操作准备就绪,则该函数应返回。如果timeout参数是空指针,则对pselect()或select()的调用将无限期地阻塞,直到至少一个描述符满足指定的条件。 要实现轮询,timeout参数不应该是空指针,而应指向零值timespec结构。

简而言之,在检查超时之前检查描述符。如果在调用select()时套接字已准备好数据,则忽略超时并立即退出select()