Unix套接字:具有多个关联集的select()执行的操作超出了它应该执行的操作

Unix Sockets: select() with more than one set associated does more than it should do

本文关键字:操作 执行 select 套接字 关联 Unix      更新时间:2023-10-16

我对tcp套接字有以下选择调用:

ret = select(nfds + 1, &rfds, &rfds2, NULL, &tv);

当我发送到大数据时使用rfds2(非阻塞模式)。rfds在那里检测我们是否在插座上收到了什么。

现在,当发送缓冲区为空时,我用rfds2检测它。但与此同时,我把插座放回了rfd,尽管我在那个插座上什么也没收到。

这是选择呼叫的预期行为吗?如何有序地区分发送和接收情况?

现在,当发送缓冲区为空时用rfds2 检测

这是不对的。select()将检测发送缓冲区何时有空间同时为OP_READ和OP_WRITE注册套接字几乎是不正确的。OP_WRITE几乎总是准备就绪,除非在发送缓冲区已满的短暂间隔内

感谢您的回答。我发现了自己的问题:错误代码在select调用之后(我如何使用FD_ISSET()来确定我可以执行的操作)。

我认为我的假设是正确的,即当确实有一些数据可以接收时,rfd中只有一个套接字。

如果套接字是非阻塞的,这似乎是预期的行为。select的手册页面对readfds参数有这样的说明:

readfds中列出的将是观察角色是否可供阅读(更多确切地说,看看阅读是否不会块特别是一个文件描述符也已就绪文件末尾)

因为套接字是非阻塞的,所以读取确实不会阻塞,因此设置该位是合理的。

它不应该引起问题,因为如果你尝试从套接字中读取,你只会一无所获,读取也不会阻塞。

根据经验,无论何时select返回,您都应该处理它指示已准备好的每个套接字,如果它返回为可读取,则读取和处理任何可用的数据,如果返回为可写入,则写入更多数据。您不应该假设每次返回时只有一个事件会发出信号。