阻塞 socket.send() 什么时候会阻塞? (UDP)

when would a blocking socket.send() block? (UDP)

我一直在阅读 python 中有关 UDP 套接字的内容。

By default a socket is configured so that sending or receiving data blocks, stopping program execution until the socket is ready. Calls to send() wait for buffer space to be available for the outgoing data, and calls to recv() wait for the other program to send data that can be read.

我理解接收部分,它必须等到另一端发送。 但为什么发送会阻塞?书上说:"send() waits for buffer space to be available"。什么是缓冲区 space?

它是针对整个操作系统还是针对每个应用程序定义的运行。

有没有办法知道有多少缓冲区 space 可用?

BSD 套接字和 POSIX 文档以及您正在阅读的任何内容所引用的缓冲区是每个 套接字 缓冲区,而不是每个 -系统或每个应用程序。它与您可以使用 SO_SNDBUF 设置的相同。当该缓冲区已满时,send 将阻塞。

但真正的问题是,为什么缓冲区会变满?

在您的应用可以看到的内容下面,内核通常有类似每个 NIC 的传输缓冲区环。当 NIC 完成将一个缓冲区的数据传输到线路上时,它会从环中拉出另一个数据。当环上有 space 时,它会从其中一个套接字缓冲区中拉出另一个传输缓冲区。或者,如果等待的缓冲区太多,它会丢弃其中的一些,然后再提取一个。因此,那部分 系统范围的(或至少是 NIC 范围的)。

因此,只知道发送缓冲区大小并不能真正告诉您您真正关心的一切,要真正了解它,您需要针对您的内核提出问题。如果那是 Linux 或 *BSD,网络堆栈是开源的并且有很好的文档记录(在 Linux 中,如果我没记错的话,如果我的 2.4 时代知识仍然有用,搜索 SO_SNDBUFtxqueuelen 给你很好的起点);否则,它可能不是。当然 Linux 暴露了 /proc 文件系统某处的所有信息,因此一旦您知道要查找的内容,就可以找到它。 *BSD 没有暴露那么多,但那里有很多东西。甚至 Windows 也有大量相关的性能计数器。