Linux UDP 套接字 : why select()?

标签 linux sockets udp

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

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

  1. 因为 UDP 是无状态的,所以 UDP 服务器只处理它收到的任何数据。新客户端发送数据后,不会创建新的套接字,对吧?

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

  3. 这是真的吗? 非阻塞 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/

相关文章:

android - "No Connected Devices",试图将我的 LG 连接到我的 Ubuntu 机器

javascript - 如何使用userAgent识别android和linux用户

macos - SO_REUSEADDR 和 SO_REUSEPORT 的行为改变了吗?

sockets - 为什么写入未连接的套接字会先发送 SIGPIPE?

java - 数据报套接字使我的 UDP 程序中的其他线程处于饥饿状态

c - 如何在 C 中为多个 UDP 数据包设置超时?

c - GStreamer - 向元素发出信号

linux - 如何使用 find 和 xargs 将文件从文件夹中的文件夹移动到另一个文件夹?

linux - 重定向域但保留原始 url

c - 在 C 中,如何 malloc 和释放一个 SOCKET(已经是一个指针)