非阻塞模式下,send和recv返回值的各种处理

非阻塞模式下,send和recv返回值的各种处理

返回值

返回值n返回值含义
大于0成功发送或接收n个字节
等于0对端关闭连接
小于0errno 为EINTR、EAGAIN、EWOULDBLOCK正常,可以继续发送或接收,其他errno则为异常,需要关闭close(fd)

场景处理

返回值大于0

send/recv write/read 函数返回值大于 0,表示成功发送或成功接收了多少字节,但是发送或者接收的字节数可能是部分字节数,比如你需要发送buf_length长度的数据,但是send/write返回的n有可能 < buf_length,这是因为发送缓冲区可能已经满了。这个时候需要注意处理这种场景,监听poll_out事件,再次触发发送,只有(n == buf_length)才算发送成功。

返回值等于0

send/recv write/read 函数返回 0,则是对端关闭了连接。
这里有一种特殊场景,就是发送端在调用send/write的时候就是填了0,即发了0字节。这种场景下底层协议栈并不会将0字节发送出去,也就是调send/write的时候避免出现此场景。

返回值小于0

不同errno的处理

返回值小于0,需要区分errno。

  • errno为EINTR、EAGAIN、EWOULDBLOCK这三个错误码,在非阻塞模式下属于正常,可以循环发送/接收,或者等待poll_in/poll_out事件触发,继续发送/接收。
  • errno为其他错误码,则需要关闭连接。
EINTR、EAGAIN、EWOULDBLOCK的产生原因
  • EINTR:当进程在一个慢系统调用中阻塞时,如果捕获到某个信号且相应信号处理函数返回时,这个系统调用不再阻塞而是被中断,就会调用返回错误(一般为-1)并设置 errno 为 EINTR。

  • EAGAIN:在非阻塞 I/O 操作中,如果由于资源限制或不满足条件导致操作无法立即完成,系统调用会返回 EAGAIN。例如,在非阻塞模式下,如果连续进行 read 操作而没有数据可读,或者在 send 函数中的 size 变量大小超过了 tcp_sendspace 的值,此时程序不会阻塞起来等待数据准备就绪返回,而是立即返回 -1,并设置 errno 为 EAGAIN。

  • EWOULDBLOCK:在某些套接字的函数操作不能立即完成时,会出现错误码 EWOULDBLOCK。实际上,在许多系统中,EAGAIN 和 EWOULDBLOCK 是同一个错误码。这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值