非阻塞套接字的手册页中详细记录了两种情况:
- 如果 send() 返回与传输缓冲区相同的长度,则整个传输成功完成,并且套接字可能处于也可能不处于返回 EAGAIN/EWOULDBLOCK 的状态,即下一次调用大于 0 字节以进行传输。
- 如果 send() 返回 -1 并且 errno 为 EAGAIN/EWOULDBLOCK,则没有任何传输完成,程序需要等待套接字准备好接收更多数据(在 epoll 情况下为 EPOLLOUT)。
非阻塞套接字没有记录的是:
- 如果 send() 返回小于缓冲区大小的正值。
假设 send() 会在多一个字节的数据上返回 EAGAIN/EWOULDBLOCK 是否安全?或者非阻塞程序是否应该再尝试一次 send() 以获得最终的 EAGAIN/EWOULDBLOCK?我担心在套接字上放置一个 EPOLLOUT 观察程序,如果它实际上没有处于“将阻塞”状态来响应它的出来。
显然,后一种策略(再次尝试得出结论)具有明确定义的行为,但它更冗长并且会影响性能。