SIGPIPE¶
产生SIGPIPE的原因¶
- 对于一个对端已经关闭的socket调用两次
write
,第二次会生成SIGPIPE;
TCP四次挥手关闭连接:TCP是全双工的,对端调用close时本意是关闭整个双工通道,本端只是收到FIN包,只能表示对端关闭了其所负责的单工道,也就是对端停止发送数据但是对端仍然可以接受数据,但实际上确实对端已经不允许发送和接收数据了
- 本端继续调用
read
,如果接收缓冲区为空,则发送ACK+FIN报文告诉对端本端已经处理完毕,之后进入LASK_ACK状态,否则接收数据直至接收缓冲区为空; - 本端继续调用
write
,如果发送缓冲区为空,则本端关闭,否则发送数据,但此时的对端已经不允许接收数据了,所以对端会回复一个RST报文,本端接收处理之后导致本端异常断开
所以是在假设本端发送缓冲区还有数据的情况下第二次调用write时将会产生SIGPIPE信号,使进程退出
- 在linux下写socket程序时,如果send数据到一个未连接的socket上,底层会抛出一个
SIGPIPE
解决方法¶
为了避免进程退出,可以捕获SIGPIPE信号,也可以选择忽略它
忽略SIGPIPE信号: