`
linkyou66
  • 浏览: 228139 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

linux 下写socket遭遇broken pipe(SIGPIPE C++)

 
阅读更多
<p>原代码片段如下,程序在第08行报错,但是try,,,catch无法抓到错误,经过debug分析是由于收到broken pipe的信号。看来程序此时被终止了;那么我期望不被终止,该怎么做了。</p>
<p><br>
01 int sendLen = 0;<br>
02 int totalLen = 0;<br>
03 int packSize = pack.size();<br>
04 while(packSize != totalLen)<br>
05 {<br>
06 try<br>
07 {<br>
08 sendLen = write(fd, const_cast&lt;char*&gt;(pack.c_str())+totalLen, packSize-totalLen);<br>
09 totalLen += sendLen;<br>
10 if(sendLen &lt;= 0)<br>
11 {<br>
12 totalLen == 0;<br>
13 fprintf(stderr,"write fd err . fd == %d - %m/n",fd);<br>
14 return false;<br>
15 }<br>
16 }<br>
17 catch (std::exception&amp; e)<br>
18 {<br>
19 printf("errrno is:%d",errno);<br>
20 std::cout &lt;&lt; "Exception: " &lt;&lt; e.what();<br>
21 }<br>
22 }<br>
23 return true;</p>
<p>在徐明刚的指导下,找到如下文章</p>
<p>网摘</p>
<p> linux下写socket的程序的时候,如果尝试send到一个disconnected socket上,就会让底层抛出一个SIGPIPE信号。
client端通过 pipe 发送信息到server端后,就关闭client端, 这时server端,返回信息给 client 端时就产生Broken pipe 信号了。
对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。如果没有调用此方法,系统就会调用默认处理方法:中止程序,显示提示信息(就是我们经常遇到的问题)。我们可以调用系统的处理方法,也可以自定义处理方法。
对一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0,
这就是常说的表示连接关闭. 但第一次对其调用write方法时, 如果发送缓冲没问题,
会返回正确写入(发送). 但发送的报文会导致对端发送RST报文,
因为对端的socket已经调用了close, 完全关闭, 既不发送, 也不接收数据. 所以,
第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出.
为了避免进程退出, 可以捕获SIGPIPE信号, 或者忽略它,
给它设置SIG_IGN信号处理函数:
signal(SIGPIPE, SIG_IGN);
这样, 第二次调用write方法时, 会返回-1, 同时errno置为SIGPIPE.
程序便能知道对端已经关闭.</p>
<p></p>
<p>为此代码变更如下;插入10行</p>
<p>01 bool CWWSimulator::SendPack(string&amp; pack, uint32_t fd)<br>
02 { <br>
03 int sendLen = 0;<br>
04 int totalLen = 0;<br>
05 int packSize = pack.size();<br>
06 while(packSize != totalLen)<br>
07 {<br>
08 try<br>
09 {<br>
10 signal(SIGPIPE, SIG_IGN);<br>
11 sendLen = write(fd, const_cast&lt;char*&gt;(pack.c_str())+totalLen, packSize-totalLen);<br>
12 totalLen += sendLen;<br>
13 if(sendLen &lt;= 0)<br>
14 {<br>
15 totalLen == 0;<br>
16 fprintf(stderr,"write fd err . fd == %d - %m/n",fd);<br>
17 return false;<br>
18 }<br>
19 }<br>
20 catch (std::exception&amp; e)<br>
21 {<br>
22 printf("errrno is:%d",errno);<br>
23 std::cout &lt;&lt; "Exception: " &lt;&lt; e.what();<br>
24 }<br>
25 } <br>
26 return true;<br>
27 }</p>
分享到:
评论

相关推荐

    linux gcc如何处理sigpipe导致的程序退出.zip

    linux gcc如何处理sigpipe导致的程序退出.zip

    C++教程网《Linux网络编程》视频百度云地址

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口)...

    [免费]2018年C++教程网的linux网络编程视频百度云下载链接.rar

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口)...

    2018年C++教程网的linux网络编程视频共41集百度云下载链接.rar

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02...

    c++教程网的linux网络编程视频下载

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口)...

    C++教程网视频:linux网络编程

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口)...

    linux网络编程

    TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用...

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

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

    进程间通信之无名管道(pipe) 完整代码

    进程间通信之无名管道(pipe) 注意: 1 只能用于具有亲缘关系的进程之间的通信 2 SIGPIPE信号的处理 七种进程间通信方式: 一 无名管道( pipe ) 二 有名管道( fifo ) 三 共享内存 shared memory 四 信号 ...

    Linux多线程服务端编程:使用muduo C++网络库

    《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...

    linux 信号量简单使用

    linux下信号量简单使用方法

    Linux网络编程 视频 教程

    Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口)...

    Linux高性能服务器编程

    1.5.2 ARP高速缓存的查看和修改 1.5.3 使用tcpdump观察ARP通信过程 1.6 DNS工作原理 1.6.1 DNS查询和应答报文详解 1.6.2 Linux下访问DNS服务 1.6.3 使用tcpdump观察DNS通信过程 1.7 socket和TCPIP协议族的...

    Linux编程从入门到精通

    10.4.3 Linux下的进程控制 312 10.5 可移植条件编译 313 10.6 补充说明 314 附录 以字母顺序排列的系统调用 315 第四部分 Linux内核概念系统结构 摘要 323 前言 324 第1章 系统结构 325 1.1 系统概述 325 1.2 内核的...

    LINUX编程白皮书 (全集)

    10.4.3 Linux下的进程控制 312 10.5 可移植条件编译 313 10.6 补充说明 314 附录 以字母顺序排列的系统调用 315 第四部分 Linux内核概念系统结构 摘要 323 前言 324 第1章 系统结构 325 1.1 系统概述 325 1.2 内核的...

    linux编程白皮书

    对深入研究Linux下的编程有很大的帮助。 目 录 雷蒙序 简介 Linux文档工程小组“公告” 译者序 第一部分 Linux内核 前言 第1章 硬件基础与软件基础 6 1.1 硬件基础 6 1.1.1 CPU 7 1.1.2 存储器 8 1.1.3 总线 8 ...

    linux网络编程-宋敬彬-part1

    2.2 Linux下的GCC编译器工具集 19 2.2.1 GCC简介 19 2.2.2 编译程序的基本知识 21 2.2.3 单个文件编译成执行文件 22 2.2.4 编译生成目标文件 22 2.2.5 多文件编译 23 2.2.6 预处理 24 2.2.7 编译成...

    LINUX编程白皮书

    对深入研究Linux下的编程有很大的帮助。 目 录 雷蒙序 简介 Linux文档工程小组“公告” 译者序 第一部分 Linux内核 前言 第1章 硬件基础与软件基础 6 1.1 硬件基础 6 1.1.1 CPU 7 1.1.2 存储器 8 1.1.3 总线 8 ...

Global site tag (gtag.js) - Google Analytics