http://blog.csdn.net/anghlq/article/details/5990513

在Unix系统下,如果send 、 recv 、 write在等待协议传送数据时 , socket 被 shutdown,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。 此种情况 应用就很难查 出 处理进程为什么退出。

SIGPIPE 信号:

对 一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0, 这就是常说的表示连接关闭. 但第一次对其调用write方法 时, 如果发送缓冲没问题, 会返回正确写入(发送). 但发送的报文会导致对端发送RST报文, 因为对端的socket已经调用了close, 完全 关闭, 既不发送, 也不接收数据. 所以, 第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出 。如果对 SIGPIPE 进行忽略处理, 二次调用write方法时, 会返回-1, 同时errno置为SIGPIPE.

处理方法:

在初始化时调用 signal(SIGPIPE,SIG_IGN) 忽略该信号(只需一次) , SIGPIPE交给了系统处理。 此时 send 、 recv 或 write 函数将返回-1,errno为EPIPE,可视情况关闭socket或其他处理

SIGPIPE 被忽略的情况下,如果 服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生,可以这样处理:  signal(SIGCHLD,SIG_IGN); 交给系统init去回收。 这样 子进程就不会产生僵尸进程了。

在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中)。

从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些非阻塞(non-blocking)操作(对文件或socket)的时候。例如,以
O_NONBLOCK的标志打开文件/socket/FIFO,如果你连续做read操作而没有数据可读。此时程序不会阻塞起来等待数据准备就绪返
回,read函数会返回一个错误EAGAIN,提示你的应用程序现在没有数据可读请稍后再试。

又例如,当一个系统调用(比如fork)因为没有足够的资源(比如虚拟内存)而执行失败,返回EAGAIN提示其再调用一次(也许下次就能成功)。

Linux - 非阻塞socket编程处理EAGAIN错误

在linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),这是什么意思?

这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。
对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。

另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。

最后,如果recv的返回值为0,那表明连接已经断开,我们的接收操作也应该结束。

当客户通过Socket提供的send函数发送大的数据包时,就可能返回一个EGGAIN的错误。该错误产生的原因是由于send

函数
中的size变量大小超过了tcp_sendspace的值。tcp_sendspace定义了应用在调用send之前能够在kernel中缓存的数据
量。当应用程序在socket中设置了O_NDELAY或者O_NONBLOCK属性后,如果发送缓存被占满,send就会返回EAGAIN的错误。

为了消除该错误,有三种方法可以选择:
1.调大tcp_sendspace,使之大于send中的size参数
---no -p -o tcp_sendspace=65536

2.在调用send前,在setsockopt函数中为SNDBUF设置更大的值

1.你自己的缓冲区满了,会返回EAGAIN。

2.你的没满,对方的缓冲区满了,肯定不关你事,可能会发送不成功,但是协议栈提供的系统调用,只管数据成功从你的缓冲区发出去,之后人家因为缓冲区满收不到数据,tcp自己有重传机制(参考Tcp/ip详解卷1)。

send()适用于已连接的数据包或流式套接口发送数据。对于数据报类套接口,必需注意发送数据长度不应超过通讯子网的IP包最大长度。IP包最大长度在WSAStartup()调用返回的WSAData的iMaxUdpDg元素中。如果数据太长无法自动通过下层协议,则返回WSAEMSGSIZE错误,数据不会被发送。
请注意成功地完成send()调用并不意味着数据传送到达。
如果传送系统的缓冲区空间不够保存需传送的数据,除非套接口处于非阻塞I/O方式,否则send()将阻塞。对于非阻塞SOCK_STREAM类型的套接口,实际写的数据数目可能在1到所需大小之间,其值取决于本地和远端主机的缓冲区大小。可用select()调用来确定何时能够进一步发送数据。

send返回值的更多相关文章

  1. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值(转载)

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  2. UNIX网络编程——关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 ...

  3. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  4. GetLastError()函数返回值及含义

    GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置.函数并无必要设置上一次错误信息,所以即使一次GetLastError调用返回的是零值, ...

  5. linux编程中接收主函数返回值以及错误码提示

    程序A创建子进程,并调用进程B,根据不调用的不同情况,最后显示结果不同. #include <stdio.h> #include <unistd.h> #include < ...

  6. [转]Linux命令的返回值

    Linux命令的返回值 对于某些监测脚本和探测命令蛮有用的: 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结束时,都会返回一个数字值,这个值叫做返回值,或者称 ...

  7. 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)

    1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...

  8. linux命令执行返回值(附错误对照表)

    转自:http://blog.sina.com.cn/s/blog_6739945f0100zt4b.html 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结 ...

  9. TCP发送接口的返回值

    原文链接: http://blog.csdn.net/ordeder/article/details/17240221 1. TCP发送接口:send() TCP发送数据的接口有send,write, ...

随机推荐

  1. ubuntu16.04.2安装完后重启报错[sda] Assuming drive cache: write through

    原因:检测主机的物理连接线,发生问题时"已连接"未勾选,重启的时候找不到iso文件 解决办法:勾选"已连接",重启机器成功

  2. DP练习 巡逻

     国庆这天五一大道上人头攒动,这是因为大家都准备从五一广场上那个大屏幕观看新中国60周年的国庆阅兵式!这虽然是一件很喜庆的事情,可却让CS市的警察局长伤透了脑筋的,因为人潮拥挤是很容易发生安全事故的. ...

  3. 27.prim算法  最优布线问题(wire.cpp)

    [例4-10].最优布线问题(wire.cpp) [问题描述] 学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来.两台计算机被连接是指它们间有数据线连接.由于计算机所处的位置不同,因此不 ...

  4. 小识.htaccess文件

    .htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户 ...

  5. Google Code Jam Africa 2010 Qualification Round Problem A. Store Credit

    Google Code Jam Qualification Round Africa 2010 Problem A. Store Credit https://code.google.com/code ...

  6. mysql 存储过程案列一个。

    -- 设置分隔符 DELIMITER // /*初始化*/ DROP PROCEDURE IF EXISTS useCursor // /*建立 存储过程 create */ CREATE PROCE ...

  7. OpenWrt包管理软件opkg的使用(极路由)

    说明: 1.OpenWrt本身系统没什么问题,关键点是一些路由器尝试的限制,比如一些厂商设置成内存分区为只读,那么这个安装软件就变得没什么意义了. 2.opkg的操作有点反人类,正常步骤是查询,安装: ...

  8. Create a DAC from a microcontroller's ADC

    Few microcontrollers include a DAC. Although you can easily find an inexpensive DAC to control from ...

  9. 程序猿怎样变身IT讲师

    我以前写过一篇文章,"一张图道尽程序猿的出路",里面有一张图: 这张图随着"一张图道尽程序猿的出路"这篇文章,以前被伯乐在线.docin(豆丁网).IT面试.J ...

  10. Google用不了解决方法(添加gmail用不了的方法)

     1. 获取google最新的ip列表 能够使用工具1: http://ip.chinaz.com/? IP=www.google.com 也能够使用工具2: http://tool.17mon.cn ...