手册页中针对非阻塞套接字有两种情况的详细记录:
没有记录的非阻塞套接字是:
是否可以安全地假设send()将对另外一个字节的数据返回EAGAIN / EWOULDBLOCK?还是非阻塞程序应该尝试再发送一次send()以获得最终的EAGAIN / EWOULDBLOCK?我担心如果EPOLLOUT监视程序实际上未处于“将要阻止”状态以响应该错误,则将它放在套接字上。
显然,后一种策略(再次尝试得出结论)具有明确的行为,但是它比较冗长,对性能造成了打击。
呼叫send有三个可能的结果:
send
调用时,发送缓冲区已 完全满send。 →如果套接字正在阻塞,则send阻塞 →如果套接字是非阻塞,则send失败并显示EWOULDBLOCK/EAGAIN
EWOULDBLOCK
EAGAIN
发生错误(例如,用户拉扯了网络电缆,对等方重置了连接)→ send失败并出现另一个错误
如果接受的字节数send小于您要求的字节数,那么这意味着发送缓冲区现在已完全填满。但是,这纯粹是间接的,对于以后的任何呼叫均不具权威性send。 返回的信息send仅仅是您调用时当前状态的“快照” send。在send返回的时间或您send再次致电时,此信息可能已过时。当您的程序在内部send,一纳秒后或在任何其他时间,网卡可能会将数据报放在线路上- 无法知道。您将知道下一次呼叫何时成功(或何时不成功)。
换句话说,但这 并不 意味着下一次调用send将返回EWOULDBLOCK/ EAGAIN(或者套接字未无阻塞会阻止)。尝试直到您所谓的“得到结论EWOULDBLOCK”才是正确的做法。