套接字可以在 EWOULDBLOCK 之后但在 epoll_wait 之前变得可写吗?

Ste*_*mer 0 sockets linux epoll

我有一个基于反应器的设计,其中许多套接字文件描述符在epoll_wait.

为了优化延迟而不是吞吐量,在写入套接字时,我们尝试立即直接写入文件描述符。

如果EWOULDBLOCK我们缓冲未写入的数据,然后等待套接字再次变得可写。

下次我们epoll_wait将文件描述符返回为可写时,我们就会从缓冲的数据中发送。

问题是,在我们收到 an之后EWOULDBLOCK但在调用之前epoll_wait,套接字是否可以写入?

也就是说,如果我们执行 2 个write调用,其中第一个调用write已部分写入,其余部分已缓冲,然后执行第二个调用write,尝试立即写入,那么套接字是否可以在第一个和第二个写调用之间变得可写,并且最终不会出现远端收到的顺序数据?

Rem*_*eau 5

问题是,在我们收到 an之后EWOULDBLOCK但在调用之前epoll_wait,套接字是否可以写入?

是的,它可以。此时EWOULDBLOCK,套接字缓冲区已满。但是,一旦对等方确认了一些数据并且套接字缓冲区中的空间被清除,套接字就会再次变得可写。这发生在代码之外的后台,因此套接字可以随时变得可写。

也就是说,如果我们执行 2 个write调用,其中第一个调用write已部分写入,其余部分已缓冲,然后执行第二个调用write,尝试立即写入,那么套接字是否可以在第一个和第二个写调用之间变得可写,并且最终不会出现远端收到的顺序数据?

是的,它可以。这将是您的代码逻辑中的一个错误,因为您在完成写入仍在等待发送的任何缓冲数据之前尝试将新数据写入套接字。

当您检测EWOULDBLOCK并开始缓冲数据时,请停止调用write()任何新数据,直到缓冲区完全清除。如果您需要发送新数据,并且缓冲区中已经有数据,只需将新数据附加到缓冲区末尾并继续,甚至根本不调用write()。每当套接字报告为可写时,请检查缓冲区中是否有任何待处理的数据,如果有,则从缓冲区的前面发送尽可能多的数据,同时删除成功发送的数据,直到缓冲区被清除或EWOULDBLOCK再次被报道。