网络socketsocket

解决ios SIGPIPE 导致的崩溃

2020-07-06  本文已影响0人  介和

1) 使用 signal(SIGPIPE, SIG_IGN) 忽略SIGPIPE。经bai实验在ios7模拟器上虽du然xcode还是会捕获SIGPIPE,但是程序不zhi会崩溃,继续后可以执行dao。但是在真机上依然会崩溃。

2) 使用 SO_NOSIGPIPE。 

int set = 1;

setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

源: https://zhidao.baidu.com/question/327689526095366005.html


3)   https://www.jianshu.com/p/b8bd5adc956b

   struct sigaction sa;

    sa.sa_handler = SIG_IGN;

    sigaction(SIGPIPE,&sa,0);

4)

产生 SIGPIPE 的条件 

      对一个已经收到 FIN 包的 socket 调用 read 方法,如果接收缓冲已空,则返回 0,这就是常说的“连接关闭”表示。

      对一个已经收到 FIN 包的 socket 第一次调用 write 方法时,如果发送缓冲没问题,则 write 调用会返回写入的数据量,同时进行数据发送。但是发送出去的报文会导致对端发回 RST 报文。因为对端的 socket 已经调用了 close 进行了完全关闭,已经处于既不发送,也不接收数据的状态。所以第二次调用 write 方法时(假设在收到 RST 之后)会生成 SIGPIPE 信号,导致进程退出(这就是为什么第二次 write 才能触发 SIGPIPE 的原因)。

民间描述:   

对一个对端已经关闭的 socket 调用两次 write,第二次 write 将会生成 SIGPIPE 信号,该信号默认结束进程。   

APUE 上的描述:   

如果在写到管道时读进程已经终止,则产生此信号(管道角度)。当类型为 SOCK_STREAM 的套接字已不再连接时,进程写到该套接字也产生此信号(socket 角度)。 

SIGPIPE 的处理方式 

为了避免进程退出,既可以对 SIGPIPE 信号进行捕获,也可以将其忽略,即为其设置 SIG_IGN 信号处理函数(在系统头文件 <signal.h> 中定义的常量): 

signal(SIGPIPE, SIG_IGN);

这样,当第二次调用 write 方法时,会返回 -1,同时 errno 会被设置成 EPIPE ,程序便能知道对端已经关闭。 

参考 : https://www.cnblogs.com/jingzhishen/p/3453727.html

        https://blog.csdn.net/weixin_34245082/article/details/91961074

上一篇下一篇

猜你喜欢

热点阅读