Linux UDP Socket:为什么选择()?

时间:2016-06-27 23:35:51

标签: linux sockets udp

我是Linux套接字编程的新手。我在这里有一个基本问题:

UDP,我们为什么需要select()

  1. 由于UDP是无状态的,因此UDP服务器只处理它收到的任何数据。一旦新客户端发送数据,就不会创建新的套接字,对吗?

  2. 如果是这样,一旦此套接字到达数据,将返回/通知select()。所以我们不需要全部检测吞吐量以检查通知哪个套接字(因为只有一个套接字);

  3. 这是真的吗? non-blocking UDP socket + select() == blocking UDP socket

  4. 谢谢!

1 个答案:

答案 0 :(得分:5)

select()的主要好处是能够一次等待多个描述符的输入。因此,当您打开多个UDP套接字时,将它们全部放入fd_set,调用select(),当它们中的任何一个收到数据包时它将返回。它返回fd_set,表示哪些数据可用。您还可以使用它等待来自网络的数据,同时还等待来自用户终端的输入。或者您可以在单个服务器中处理UDP和TCP连接(例如,可以使用TCP或UDP访问DNS服务器)。

如果您不使用select(),则必须编写一个循环,在每个套接字上连续执行非阻塞读取。这不是那么有效,因为它会花费大量时间执行不必要的系统调用(想象一下,服务器每天只能获得一个请求,但却不断地整天调用recv()

您的问题似乎假设服务器只能使用一个UDP套接字。但是,如果服务器有多个IP地址,则可能需要多个套接字。 UDP客户端通常期望响应来自他们发送请求的相同IP。标准套接字API不提供知道请求发送到哪个IP的方法,或者设置传出回复的源地址。因此,实现此目的的常用方法是打开绑定到每个IP的单独套接字,并使用select()epoll()同时等待所有这些请求。然后通过收到请求的同一个套接字发送回复,它将使用该套接字的绑定IP作为源。

(Linux具有不必要的套接字扩展,请参阅Setting the source IP for a UDP socket。)