`
linkyou66
  • 浏览: 234865 次
  • 性别: 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网络编程socket错误码分析

    Linux 网络编程 socket 错误码分析 在 Linux 网络编程中,socket 函数可能会返回多种错误码,这些错误码提供了有价值的信息,可以帮助开发者诊断和处理网络编程中的问题。本文档总结了常见的 socket 错误码及其处理...

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

    在处理涉及网络通信或管道(pipe)的程序时,可能会遇到一个名为`SIGPIPE`的信号。`SIGPIPE`信号是在进程尝试向一个已关闭的管道、socket或其他类型的数据流写入数据时产生的。这种情况下,系统会发送一个`SIGPIPE`...

    Linux socket错误分析

    Linux系统下socket编程是网络编程的核心部分,涉及到进程间通信与网络资源的交互。在进行socket编程时,经常需要处理不同的错误码,这些错误码帮助开发者了解程序运行过程中遇到的具体问题。在Linux中,socket错误码...

    Linux网络编程socket错误码分析[参考].pdf

    在非阻塞模式下,如果 socket 是非阻塞的,并且写缓冲队列已满,可以做延时后再重试。如果 recv 返回值小于请求的长度时,说明缓冲区已经没有可读数据,但再读不一定会触发 EAGAIN,可能返回 0,表明 TCP 连接已被...

    Linux网络编程socket错误码分析.pdf

    Linux 网络编程 socket 错误码分析 Linux 网络编程中,了解 socket 错误码非常重要,因为它们可以帮助开发者诊断和解决网络编程中的问题。本文将对常见的 socket 错误码进行分析,帮助开发者更好地理解和处理这些...

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

    4. **非阻塞写操作**:将Socket设置为非阻塞模式,这样write操作在失败时会立即返回错误,而不是等待并最终触发SIGPIPE信号。 5. **使用send()和recv()替代write()和read()**:send()和recv()函数提供了更多的控制...

    Linux下Socket编程.docx

    在Linux环境下进行Socket编程时,与Windows平台相比,存在一些关键差异。首先,涉及网络通信的头文件不同,Windows系统使用`winsock.h`或`winsock2.h`,而Linux则采用`sys/socket.h`。在错误处理方面,Windows下通常...

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

    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四层模型 基本概念(对等通信、封装、分用、端口)...

    socket server关闭时导致socket client也关闭 的原因及解决办法

    在Linux环境下,SIGPIPE信号默认的行为是终止进程。这就是为什么在Server关闭后,Client也可能跟着关闭的原因。而在Windows系统中,这种行为有所不同,不会直接引发进程崩溃,而是返回一个错误代码。 为了解决这个...

    LINUX SOCKET错误分析

    ### LINUX SOCKET错误分析 在LINUX网络编程过程中,开发者经常会遇到一些特定的错误码,比如EINTR、ETIMEOUT、EAGAIN等。这些错误码对于理解网络编程中的异常情况至关重要。下面我们将详细介绍这些错误码的含义及其...

    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四层模型 基本概念(对等通信、封装、分用、端口)...

    Socket编程的发送接收消息函数

    Socket编程是计算机网络通信的核心技术之一,特别是在分布式系统和客户端-服务器应用中广泛使用。本文主要探讨Socket编程中用于发送和接收消息的关键函数——send和recv。 send函数是用来向TCP连接的另一端发送数据...

    pipe2.4 源代码

    在Linux系统编程中,管道(Pipe)是一种基本的进程间通信机制,允许父子进程或者兄弟进程之间进行数据传输。`pipe2.4`可能是指针对Linux内核版本2.4的管道实现或相关的源代码示例。在这个版本的内核中,管道功能已经...

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

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

    Linuxsocket错误分析[参考].pdf

    在Linux网络编程中,Socket是用于进程间通信的重要工具,特别是在网络应用程序中。本文将深入解析Linux Socket编程中常见的错误及其含义,帮助开发者更好地理解和处理这些问题。 1. **EINTR** (4): 这个错误表示...

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

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

    pipe函数管道通信小例子

    在Linux中,通过`pipe()`函数创建一个管道。该函数接受一个整型数组作为参数,返回值为零表示成功,非零值表示失败。该数组包含两个元素,第一个元素是读端,第二个元素是写端。例如: ```c int pipe(int fd[2]); `...

    Linux下C语言编程--信号处理函数.

    ### Linux下C语言编程——信号处理函数 #### 一、信号的基本概念与产生 在Linux系统中,**信号**是一种轻量级的进程间通信机制,用于通知接收进程某个特定事件的发生。它不仅可以由硬件异常(如除零错误)触发,也...

Global site tag (gtag.js) - Google Analytics