我对tcp套接字进行了以下select调用:
ret = select(nfds + 1, &rfds, &rfds2, NULL, &tv);
当我发送到大数据(非阻塞模式)时使用rfds2。并且rfds可以检测我们是否在插座上收到了什么东西。
现在,当发送缓冲区为空时,我用rfds2检测它。但同时我将套接字放回到rfds中,尽管我在该套接字上没有收到任何内容。
这是select-call的预期行为吗?如何区分发送和接收案例?
答案 0 :(得分:1)
现在,当发送缓冲区为空时,我 用rfds2检测它
这不正确。 select()将检测发送缓冲区何时有空间。同时为OP_READ和OP_WRITE注册套接字几乎没有问题。除了发送缓冲区已满的短暂间隔外,OP_WRITE几乎总是准备就绪。
答案 1 :(得分:1)
感谢您的回答。我找到了自己的问题:
错误的代码是在选择调用之后(我如何使用FD_ISSET()
来确定我可以执行的操作)。
我认为我的假设是正确的,rfds中只有一个套接字,当有一些数据可以接收时。
答案 2 :(得分:-1)
如果套接字是非阻塞的,那似乎是预期的行为。 select的手册页有关于readfds参数的说法:
readfds中列出的内容将是 看着角色是否变成了 可供阅读(更多 确切地说,看看是否会读 块;特别是一个文件 描述符也准备就绪 结束文件)
因为套接字是非阻塞的,所以读取不会阻塞,因此设置该位是合理的。
它不应该导致问题,因为如果您尝试从套接字读取,您将只返回任何内容并且读取不会阻止。
根据经验,每当select返回时,你应该处理它指示准备就绪的每个套接字,如果它返回为准备读取,则读取和处理可用的任何数据,或者如果它返回为就绪,则写入更多数据-来写。您不应该假设每次返回时只会发出一个事件的信号。