繁体   English   中英

UDP非阻塞写入失败

[英]UDP non blocking write failure

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

同样,如果没有可用数据,则UDP读取( recvfrom )可能会失败。 但是UDP写入( sendto )失败的情况是什么? 我认为在UDP写中不会有任何非阻塞错误。 因为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套接字(即使远程对等方的接收窗口未满)也可能会遇到同样的问题。内核缓冲区。

因为TCP写入发送数据并等待来自另一端的ACK。

不,不是。 它将您的数据复制到套接字发送缓冲区,如果缓冲区已满,它将阻塞或返回-1/EWOULDBLOCK/EAGAIN.

但这不是UDP写入的情况,它只会发送并出来,它不会等待来自对等方的任何ACK。

不,不是。 它将您的数据复制到套接字发送缓冲区,如果缓冲区已满,它将阻塞或返回-1/EWOULDBLOCK/EAGAIN.

在这两种情况下,将字节实际写入网络都是与程序异步的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM