我试图测试由对等方优雅地关闭的已关闭套接字,而不会产生双重发送以引发 SIGPIPE
的延迟损失。
这里的假设之一是,套接字如果关闭,则是在其最后的写入/发送后立即被对等方优雅地关闭的。实际的错误,例如过早关闭,在代码的其他位置处理。
如果套接字仍然打开,将有0或更多字节的数据,我实际上不想从套接字缓冲区中提取这些数据。
我想到可以调用 int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);
来确定套接字是否仍连接着。如果它仍然连接,但缓冲区中没有数据,我将得到 -1
的返回值,并且 errno == EAGAIN
,并返回 sockfd 以供重复使用。如果它已经被对等方优雅地关闭,则我将得到 ret == 0
并打开一个新连接。
我已经测试过这个方法,看起来是有效的。但是,我怀疑在我接收到最后一位数据和对等方发送 FIN
之间可能存在一个很小的时间窗口,在这个时间窗口内我的测试 recv
可能会出现错误的 EAGAIN
。
这会对我产生影响吗?还是有更好的方法可以做到这一点?