跳转至

SIGPIPE

产生SIGPIPE的原因

  1. 对于一个对端已经关闭的socket调用两次write,第二次会生成SIGPIPE;

TCP四次挥手关闭连接:TCP是全双工的,对端调用close时本意是关闭整个双工通道,本端只是收到FIN包,只能表示对端关闭了其所负责的单工道,也就是对端停止发送数据但是对端仍然可以接受数据,但实际上确实对端已经不允许发送和接收数据了

  1. 本端继续调用read,如果接收缓冲区为空,则发送ACK+FIN报文告诉对端本端已经处理完毕,之后进入LASK_ACK状态,否则接收数据直至接收缓冲区为空;
  2. 本端继续调用write,如果发送缓冲区为空,则本端关闭,否则发送数据,但此时的对端已经不允许接收数据了,所以对端会回复一个RST报文,本端接收处理之后导致本端异常断开

所以是在假设本端发送缓冲区还有数据的情况下第二次调用write时将会产生SIGPIPE信号,使进程退出

  1. 在linux下写socket程序时,如果send数据到一个未连接的socket上,底层会抛出一个SIGPIPE

解决方法

为了避免进程退出,可以捕获SIGPIPE信号,也可以选择忽略它

忽略SIGPIPE信号:

#include <signal.h>

signal(SIGPIPE, SIG_IGN);