Linux SIGPIPE信号产生原因与解决方法

21 篇文章 4 订阅
18 篇文章 0 订阅

潜水同行技术群,有人遇到如下场景,拿出来分享/记录,
场景:
大厂的嵌入式平台,多个厂家,多进程间socket通信.,
A进程作为客户端,连接作为服务器的B进程,

A连接B,顺畅
A进程close此套接字
A连接B,失败




最后发现,A进程close套接字,导致B进程直接退出.

原因

SIGPIPE(Broken pipe)

Broken pipe: write to pipe with no readers.
管道破裂。这个信号通常在进程间通信产生,比如采用FIFO(管道)通信的两个进程,读管道没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。此外用Socket通信的两个进程,写进程在写Socket的时候,读进程已经终止

其他信号含义,参见:
linux 信号类别/列表-概述

解决方法

忽略SIGPIPE信号

struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &sa, 0 );

调整socket发送函数的flags参数

设置flags为MSG_NOSIGNAL,实现整个进程(而非仅仅调用的线程)忽略SIGPIPE信号的效果.

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,\
                      const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

参数flags,指示了send 的传输数据的方式:

MSG_CONFIRM 提供链路层反馈以保持地址映射有效

MSG_DONTROUTE 勿将数据包路由出本地网络

MSG_DONTWAIT 允许非阻塞行为

MSG_EOF 标记记录结束

MSG_MORE 允许延迟并写更多数据

MSG_NOSIGNAL:
如果面向流的套接字上的对等方已关闭连接,则不要生成SIGPIPE信号。仍然返回EPIPE错误。这提供了类似于使用sigaction(2)忽略SIGPIPE的行为;尽管MSG_NOSIGNAL是每个调用的特性,但是,忽略SIGPIPE设置了一个影响进程中所有线程的进程属性。

MSG_OOB 允许发送带外数据

参考:

Linux SIGPIPE信号产生原因与解决方法
客户端断开socket连接, 服务端send 向一个失效的socket 发送数据,导致服务的进程退出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值