本文介绍了当非阻塞发送()只传输部分数据,我们可以假设它会返回EWOULDBLOCK下一个电话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两种情况详细记录在手册页非阻塞套接字:

Two cases are well-documented in the man pages for non-blocking sockets:


  • 如果发送()返回相同长度的转移缓冲液,整个传输的成功完成,并且插座可以是或可以不是在返回EAGAIN / EWOULDBLOCK与下一呼叫的状态> 0字节传输。

  • 如果发送()返回-1并将errno是EAGAIN / EWOULDBLOCK,无转移的结束,并且程序需要等到插槽中安装更多的数据(EPOLLOUT在epoll的情况下, )。

  • If send() returns the same length as the transfer buffer, the entire transfer finished successfully, and the socket may or may not be in a state of returning EAGAIN/EWOULDBLOCK the next call with >0 bytes to transfer.
  • If send() returns -1 and errno is EAGAIN/EWOULDBLOCK, none of the transfer finished, and the program needs to wait until the socket is ready for more data (EPOLLOUT in the epoll case).

有什么理由不为文档非阻塞套接字是:

What's not documented for nonblocking sockets is:


  • 如果发送()返回大于缓冲区的大小越小的正值。

它是安全的假设,在send()将返回的数据,甚至多一个字节EAGAIN / EWOULDBLOCK?还是应该非阻塞程序试图发送()更多的时间来得到一个结论性的EAGAIN / EWOULDBLOCK?我担心把插座上的EPOLLOUT守望者,如果它实际上不是一个会阻塞状态,它出来的反应。

Is it safe to assume that the send() would return EAGAIN/EWOULDBLOCK on even one more byte of data? Or should a non-blocking program try to send() one more time to get a conclusive EAGAIN/EWOULDBLOCK? I'm worried about putting an EPOLLOUT watcher on the socket if it's not actually in a "would block" state to respond to it coming out of.

显然,后者的策略(试图再次得到的东西确凿)具有良好定义的行为,但它更详细,并提出一击的表现。

Obviously, the latter strategy (trying again to get something conclusive) has well-defined behavior, but it's more verbose and puts a hit on performance.

推荐答案

一个调用有三种可能的结果:

A call to send has three possible outcomes:


  1. 有一个在发送缓冲区和RARR提供至少一个字节; 发送成功并返回接受字节(可能不到你要的)的数量

  2. 发送缓冲区的完全充满的你叫发送时间。结果
    →如果套接字是阻塞,发送块结果
    →如果套接字是非阻塞,发送失败 EWOULDBLOCK / EAGAIN

  3. 发生错误(例如,用户拉网线,通过对等连接复位)RARR; 发送失败,另一个错误

  1. There is at least one byte available in the send buffer →send succeeds and returns the number of bytes accepted (possibly fewer than you asked for).
  2. The send buffer is completely full at the time you call send.
    →if the socket is blocking, send blocks
    →if the socket is non-blocking, send fails with EWOULDBLOCK/EAGAIN
  3. An error occurred (e.g. user pulled network cable, connection reset by peer) →send fails with another error

如果按接受的字节数发送比你要求的,量少那么这结果意味着发送缓冲区现在完全充满。然而,这对于任何将来调用纯属间接和非权威的,以发送。结果
通过返回的信息发送仅仅是一个你调用时的当前状态的快照发送。由时间发送返回或通过调用时间发送再次,这个信息可能已经过时。该网卡可以把数据报上线,而你的程序是在发送或纳秒之后,或在其他任何时间 - 也没有办法知道。你会知道什么时候该下一次调用成功(或当事实并非如此)。

If the number of bytes accepted by send is smaller than the amount you asked for, then this consequently means that the send buffer is now completely full. However, this is purely circumstantial and non-authorative in respect of any future calls to send.
The information returned by send is merely a "snapshot" of the current state at the time you called send. By the time send has returned or by the time you call send again, this information may already be outdated. The network card might put a datagram on the wire while your program is inside send, or a nanosecond later, or at any other time -- there is no way of knowing. You'll know when the next call succeeds (or when it doesn't).

在换句话说,这样做的不可以意味着下一次调用发送将返回 EWOULDBLOCK / EAGAIN (或会阻止如果套接字是不是非阻塞)。尝试,直到你叫什么得到一个结论性的 EWOULDBLOCK 是做正确的事。

In other words, this does not imply that the next call to send will return EWOULDBLOCK/EAGAIN (or would block if the socket wasn't non-blocking). Trying until what you called "getting a conclusive EWOULDBLOCK" is the correct thing to do.

这篇关于当非阻塞发送()只传输部分数据,我们可以假设它会返回EWOULDBLOCK下一个电话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 16:45