我知道关闭对等端的套接字时会引发管道破裂错误。但是,在我的测试中,我注意到当对等端关闭时,在此端立即进行“发送”调用并不总是会导致管道错误。例如:关闭对等端的套接字后(我尝试通过调用close进行干净关闭,也通过杀死对等体来异常关闭),如果我尝试发送40个字节,那么管道不会中断,但是,如果我尝试发送40000字节,则立即给出管道中断错误。到底是什么原因导致管道破裂,并且可以预测其行为?
3 回答
皈依舞
TA贡献1851条经验 获得超3个赞
观察网络可能要花费一些时间-总的来说,关闭后的总时间大约为2分钟(是的,几分钟!),然后才假定发往该端口的数据包全部失效。在某些时候检测到错误情况。只需少量写入,您就可以在系统的MTU中,因此消息已排队等待发送。大量写入时,您比MTU还要大,系统会更快地发现问题。如果忽略SIGPIPE信号,则函数将在管道断开时返回EPIPE错误-在检测到连接断开的某个时候。
qq_花开花谢_0
TA贡献1835条经验 获得超7个赞
套接字的当前状态由“保持活动”活动确定。在您的情况下,有可能在发出send调用时,keep-alive活动会告知套接字处于活动状态,因此send调用会将所需的数据(40字节)写入缓冲区,并返回而不会出现任何错误。
当您发送更大的块时,发送调用将进入阻塞状态。
发送手册页也确认了这一点:
当消息不适合套接字的发送缓冲区时,除非套接字已置于非阻塞I / O模式,否则send()通常会阻塞。在非阻塞模式下,在这种情况下它将返回EAGAIN
因此,在阻塞空闲可用缓冲区的同时,如果(通过保持活动机制)通知调用方另一端不再存在,则发送调用将失败。
使用所提到的信息很难预测出确切的情况,但是我相信,这应该是您遇到问题的原因。
人到中年有点甜
TA贡献1895条经验 获得超7个赞
也许40个字节适合管道缓冲区,而40000个字节不适合吗?
编辑:
当您尝试写入关闭的管道时,发送过程将发送SIGPIPE信号。我不确切地知道什么时候发送信号,或者管道缓冲区对此有什么影响。您可以通过使用sigaction调用捕获信号来恢复。
- 3 回答
- 0 关注
- 590 浏览
添加回答
举报
0/150
提交
取消