gpt4 book ai didi

c - UDP 非阻塞写入失败

转载 作者:太空宇宙 更新时间:2023-11-04 00:18:33 25 4
gpt4 key购买 nike

我曾在非阻塞 TCP 工作过,因为在非阻塞情况下读取和写入都可能失败。如果没有可用数据,TCP 非阻塞读取可能会失败,如果对等方的 TCP 缓冲区已满(我希望 TCP 缓冲区大小为 64K),TCP 写入可能会失败。

类似地,如果没有可用数据,UDP 读取 (recvfrom) 可能会失败。但是 UDP 写入 (sendto) 的失败案例是什么?我认为在 UDP 中写入不会有任何非 block 错误。因为 TCP 写入发送数据并等待来自另一方的 ACK。但对于 UDP 写入而言,情况并非如此,它只会发送并发出,并且不会等待来自对等方的任何 ACK。如果它不发送到另一端意味着它的数据包丢失。

我对 UDP 非阻塞写的理解是否正确?请解释一下?

最佳答案

UDP 非阻塞发送失败的最可能原因是 UDP 套接字的内核传出数据缓冲区已满。在这种情况下,send()/sendto() 将返回 -1 并且 errno 将设置为 EWOULDBLOCK。

请注意,非阻塞 send()/sendto() 在数据返回之前实际上并没有将数据发送出网络设备;相反,它将数据复制到内核缓冲区中并立即返回,此后内核负责尽快将该数据移出网络。如果您的程序试图一次发送大量数据,传出数据缓冲区可能会变满,因为 CPU 将新数据添加到缓冲区的速度比网络硬件将缓冲区数据转发到网络的速度快得多。

如果您收到 -1/EWOULDBLOCK 错误,通常最优雅的处理方法是停止尝试在该套接字上发送,直到套接字 select()(或 poll() 等)作为准备好写了。发生这种情况时,您就知道内核缓冲区至少已部分耗尽,您可以再次尝试调用 send()/sendto()。

另一个(不太可能)导致 send() 出错的原因是您尝试发送到的 IP 地址无效。在任何情况下,您都应该检查 errno 并找出 errno 值是多少,因为这将使您更好地了解问题出在哪里。

顺便说一句,上述行为也不是 UDP 独有的;如果您尝试在套接字上发送()数据的速度快于本地网卡耗尽套接字的速度,那么您可以并且将会遇到与非阻塞 TCP 套接字相同的问题(即使远程对等方的接收窗口未满)内核缓冲区。

关于c - UDP 非阻塞写入失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20196064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com