我是Linux套接字编程的新手。我在这里有一个基本问题:
UDP
,我们为什么需要select()
?
由于UDP
是无状态的,因此UDP服务器只处理它收到的任何数据。一旦新客户端发送数据,就不会创建新的套接字,对吗?
如果是这样,一旦此套接字到达数据,将返回/通知select()
。所以我们不需要全部检测吞吐量以检查通知哪个套接字(因为只有一个套接字);
这是真的吗? non-blocking UDP socket
+ select()
== blocking UDP socket
。
谢谢!
答案 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。)