Linux中管道中断信号SIGPIPE
在TCP通信双方中,为了描述方便,以下将通信双方用A和B代替。根据TCP协议规定,如果A关闭连接后B继续发送数据,B会收到A的RST响应。若B继续发送数据,系统会发出SIGPIPE信号告知连接已断开,停止发送。系统对SIGPIPE信号的默认处理行为是让B进程退出。操作系统对SIGPIPE信号的这种默认处理行为非常不友好,让我们来分析一下。TCP通信是全双工信道,相当于两条单工信道,连接两端各负责一条。当对端“关闭”时,虽然本意是关闭整个两条信道,但本端只是收到FIN包。根据TCP协议的规定,当一端关闭其负
在 TCP 通信双方中,为了描述方便,以下将通信双方用 A 和 B 代替。
根据TCP协议规定,如果A关闭连接后B继续发送数据,B会收到A的RST响应。若B继续发送数据,系统会发出SIGPIPE信号告知连接已断开,停止发送。
系统对 SIGPIPE 信号的默认处理行为是让 B 进程退出。
操作系统对 SIGPIPE 信号的这种默认处理行为非常不友好,让我们来分析一下。

TCP通信是全双工信道,相当于两条单工信道,连接两端各负责一条。
当对端“关闭”时, 虽然本意是关闭整个两条信道,但本端只是收到 FIN 包。
根据TCP协议的规定,当一端关闭其负责的单向通道时,仍可接收数据但不再发送数据。
也就是说,因为 TCP 协议的限制,通信一方无法获知对端的 socket 是调用了 close 还是 shutdown。
int shutdown(int socket, int how);
shutdown 函数的参数 how 可以设置为关闭 SHUT_RD、SHUT_WR 或 SHUT_RDWR 用于表示关闭收、发单个通道或者同时关闭收发通道。
对一个已经收到 FIN 包的 socket 调用 read/recv 方法, 如果接收缓冲已空,则返回 0,这就是常说的表示连接关闭。但第一次对其调用 write/send 方法时,如果发送缓冲没问题,会返回正确写入(即 write/send 函数返回值大于 0),但发送的报文会导致对端回应 RST 报文。因为上一次程序调用 write/send 是正常的,再次尝试调用 write/send 函数时因产生 SIGPIPE 信号导致进程退出。
这种默认行为对于我们开发程序,尤其是对于后端服务,需要同时对许多客户端服务,不能因为与某一个客户端的连接出问题了而导致整个进程退出不能继续为其他客户端服务。
为了避免这种现象出现, 可以捕获 SIGPIPE 信号并对其进行处理或者忽略该信号, 忽略该信号代码如下:
signal(SIGPIPE, SIG_IGN);
这样设置后,第二次调用 write/send 方法时,会返回 -1,同时 errno 错误码被置为 SIGPIPE,程序便能知道对端已经关闭。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















