套接字:选择(readfds、writefds、 exceptfds)

问题描述 投票:0回答:1

每个类别中的描述符集有何用途?我不明白其意图,为什么可以在可读集中写入并从可写集中读取?是什么让套接字做好写准备?

在我见过的所有示例中,除了读取组之外,这些组的管理都是手动完成的。那么问题来了,为什么可以在可读组中写入数据呢?还有为什么写组里可以读呢?因为这样的话这些组的意义就丢失了,并且对于每个组都需要编写相同的控制逻辑?

linux sockets unix select multiplexing
1个回答
0
投票

为什么可以在可读集中写入并从可写集中读取?

每个集合就是:一组整数,集合中的每个整数代表属于该集合的一个套接字。所以你不能从集合中“读”或“写”;您只能将整数添加到集合中,也可以不添加它们。

请注意,这与在单个套接字本身上调用

recv()
send()
的主题完全不同,您可以随时在任何套接字上执行此操作,无论您将什么放入选择集中。

读取集指定您想要导致

select()
返回的套接字,一旦它们准备好读取(即,只要其中至少一个具有可供您收集的数据)致电
recv()
)。

写入集指定您想要导致

select()
返回的套接字,一旦它们准备好写入(即,只要其中至少一个具有可用的传出缓冲区空间,以便您可以调用
send()
并立即将至少一些数据放入其传出数据缓冲区中)。

使用 except-set(通常以特定于操作系统的方式)来通知您某些套接字存在异常情况。我建议暂时忽略这个集合,只传递 NULL 作为它的参数;大多数用途都不需要它。

什么使套接字可写?

当套接字的传出数据缓冲区未完全满时,套接字就处于写就绪状态。 (即,当您可以对其调用

send()
并且
send()
能够将至少一个字节的数据放入缓冲区时,因此不必阻塞或返回
-1/EWOULDBLOCK

那么问题来了,为什么可以在可读组中写入数据呢?

始终可以在任何套接字上调用

send()
write()
。即使您也有兴趣在该套接字准备好读取时返回
select()
,这仍然是正确的。

还有为什么写组里可以读?

始终可以在任何套接字上调用

recv()
read()
。即使您也有兴趣在该套接字准备好写入时返回
select()
,这仍然是正确的。

因为这样这些组的意义就丢失了,并且每个组都需要编写相同的控制逻辑?

事实并非如此。这些组的含义与您希望

select()
调用的行为方式相关 - 特别是,什么套接字状态应导致
select()
返回。它与您在 select() 返回后实际对套接字进行
do
的操作无关;这取决于你。

© www.soinside.com 2019 - 2024. All rights reserved.