我是 Linux 套接字编程的新手。我有一个基本问题:
对于UDP
,为什么我们需要select()
?
因为
UDP
是无状态的,所以 UDP 服务器只处理它收到的任何数据。新客户端发送数据后,不会创建新的套接字,对吧?如果是这样,一旦此套接字有数据到达,
select()
将被返回/通知。所以我们不需要通过所有的吞吐量来检查通知了哪个套接字(因为只有一个套接字);这是真的吗?
非阻塞 UDP 套接字
+select()
==阻塞 UDP 套接字
。
谢谢!
最佳答案
select()
的主要好处是能够同时等待多个描述符的输入。因此,当您打开多个 UDP 套接字时,将它们全部放入 fd_set
,调用 select()
,当其中任何一个接收到数据包时它将返回。它返回一个 fd_set
指示哪些有可用数据。您还可以使用它来等待来自网络的数据,同时也等待来自用户终端的输入。或者您可以在单个服务器中同时处理 UDP 和 TCP 连接(例如,可以使用 TCP 或 UDP 访问 DNS 服务器)。
如果您不使用 select()
,您将不得不编写一个循环,在每个套接字上连续执行非阻塞读取。这不是那么有效,因为它会花费大量时间执行不必要的系统调用(想象一个服务器一天只收到一个请求,但整天都在不断调用 recv()
)。
您的问题似乎假设服务器只能使用一个 UDP 套接字。但是,如果服务器有多个 IP 地址,则可能需要多个套接字。 UDP 客户端通常希望响应来自他们向其发送请求的同一 IP。标准套接字 API 不提供知道请求发送到哪个 IP 或设置传出回复的源地址的方法。所以实现这个的常见方法是打开一个单独的套接字绑定(bind)到每个 IP,并使用 select()
或 epoll()
等待所有的请求同时。然后您通过接收请求的同一个套接字发送回复,它将使用该套接字的绑定(bind) IP 作为源。
(Linux 有套接字扩展,使它变得不必要,参见 Setting the source IP for a UDP socket。)
关于Linux UDP 套接字 : why select()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38064831/