简体   繁体   English

UDP非阻塞写入失败

[英]UDP non blocking write failure

I have worked in non blocking TCP, in that both read and write can fail in non blocking case. 我曾在非阻塞TCP中工作,因为在非阻塞情况下读写都可能失败。 TCP non blocking read can fail if there is no data available and TCP write can fail if peer side`s TCP buffer is full (I hope TCP buffer size is 64K). 如果没有可用数据,则TCP非阻塞读取可能会失败,如果对端的TCP缓冲区已满(我希望TCP缓冲区大小为64K),则TCP写入会失败。

Similarly UDP read ( recvfrom ) can fail if no data available. 同样,如果没有可用数据,则UDP读取( recvfrom )可能会失败。 But what is the failure case for UDP write ( sendto ). 但是UDP写入( sendto )失败的情况是什么? I think in UDP write there will not be any non block error. 我认为在UDP写中不会有任何非阻塞错误。 Because TCP write sends data and wait for the ACK from other side. 因为TCP写入发送数据并等待来自另一端的ACK。 But this is not the case for UDP write it will just send and comes out and it doesnt wait for any ACK from peer side. 但这不是UDP写入的情况,它只会发送并出来,它不会等待来自对等方的任何ACK。 If its not send to other side means its packet loss. 如果它没有发送到另一侧,则意味着其数据包丢失。

Whether my understanding of UDP non blocking write is correct ? 我对UDP非阻塞写入的理解是否正确? Please explain ? 请解释 ?

The most likely reason why a UDP non-blocking send would fail is that the UDP socket's in-kernel outgoing-data buffer is full. UDP非阻塞发送失败的最可能原因是UDP套接字的内核内传出数据缓冲区已满。 In this case, send()/sendto() would return -1 and errno would be set to EWOULDBLOCK. 在这种情况下,send()/ sendto()将返回-1,而errno将被设置为EWOULDBLOCK。

Note that a non-blocking send()/sendto() doesn't actually send the data out the network device before it returns; 请注意,非阻塞send()/ sendto()实际上不会在数据返回之前将其发送出网络设备。 rather it copies the data into an in-kernel buffer and returns immediately, and thereafter it is the kernel's responsibility to move that data out to the network as quickly as it can. 而是将数据复制到内核缓冲区中并立即返回,此后,内核负责将数据尽快移至网络。 The outgoing-data buffer can become full if your program tries to send a lot of data at once, because the CPU can add your new data to the buffer much faster than the network hardware can forward the buffer's data out to the network. 如果您的程序尝试一次发送大量数据,则传出数据缓冲区可能已满,因为CPU可以将您的新数据添加到缓冲区中的速度比网络硬件将缓冲区数据转发到网络中的速度要快得多。

If you get a -1/EWOULDBLOCK error, usually the most graceful way to handle it is to stop trying to send on that socket until the socket select()'s (or poll()'s, or etc) as ready-for-write. 如果收到-1 / EWOULDBLOCK错误,通常最优雅的处理方法是停止尝试在该套接字上发送,直到套接字select()(或poll()等)准备就绪为止-写。 When that happens, you know that the in-kernel buffer has been at least partially drained, and you can try the send()/sendto() call again. 发生这种情况时,您知道内核缓冲区至少已耗尽一部分,可以再次尝试send()/ sendto()调用。

Another (less likely) cause of an error from send() would be if the IP address you are trying to send to is invalid. send()错误的另一个(不太可能)原因是,如果您尝试发送到的IP地址无效。 In any case, you should check errno and find out what the errno value is, as that will give you better insight into what is going wrong. 无论如何,您都应该检查errno并找出errno值是什么,因为这样可以使您更好地了解问题所在。

Btw the behavior described above is not unique to UDP, either; 顺便说一下,上述行为也不是UDP独有的。 you can and will have the same problem with a non-blocking TCP socket (even if the remote peer's receive window is not full) if you try to send() data on the socket faster than the local network card can drain the socket's in-kernel buffer. 如果您尝试在套接字上发送()数据的速度快于本地网卡可能耗尽套接字的输入,则非阻塞TCP套接字(即使远程对等方的接收窗口未满)也可能会遇到同样的问题。内核缓冲区。

Because TCP write sends data and wait for the ACK from other side. 因为TCP写入发送数据并等待来自另一端的ACK。

No it doesn't. 不,不是。 It copies your data into the socket send buffer, and if that is full it either blocks or returns -1/EWOULDBLOCK/EAGAIN. 它将您的数据复制到套接字发送缓冲区,如果缓冲区已满,它将阻塞或返回-1/EWOULDBLOCK/EAGAIN.

But this is not the case for UDP write it will just send and comes out and it doesnt wait for any ACK from peer side. 但这不是UDP写入的情况,它只会发送并出来,它不会等待来自对等方的任何ACK。

No it doesn't. 不,不是。 It copies your data into the socket send buffer, and if that is full it either blocks or returns -1/EWOULDBLOCK/EAGAIN. 它将您的数据复制到套接字发送缓冲区,如果缓冲区已满,它将阻塞或返回-1/EWOULDBLOCK/EAGAIN.

In both cases the actual putting of bytes onto the wire is asynchronous to your program. 在这两种情况下,将字节实际写入网络都是与程序异步的。

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

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