socket编程:recv/send 和 recv/recvfrom返回值及处理

本文详细解析了socket编程中recv和recvfrom的返回值情况,当返回值为0时,表明连接已关闭;大于0且小于缓冲区大小时,数据读取完成;小于0时,根据errno判断是否为临时阻塞或中断,否则表示读取失败。对于send和sendto,返回值指示实际发送的数据量,未发送完应继续尝试,遇到EAGAINE、EWOULDBLOCK或EINTR可继续等待或重试,否则表示发送出错。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1、recv 和 recvfrom
      =0  当返回值为0时,表示对端已经关闭了这个链接,我们应该自己关闭这个链接,即close(sockfd)。另外因为异步操作会用select或 epoll做事件触发,所以:

       ① 如果使用select,应该使用FD_CLR(sockfd,fd_set)将sockfd清除掉,不再监听
       ② 如果使用epoll,系统会自己将 sockfd 清除掉,不再进行监听。

       >0 当返回值大于0 且 小于 sizeof(buffer) 时,表示数据肯定读完。(如果等于sizeof(buffer),可能有数据还没读,应该继续读,不可能有大于)
       <0 当返回值小于0,即等于-1时,分情况判断:
        ① 如果   errno   为  EAGAINE 或 EWOULDBLOCK /* Operation would block */                                    
             表示暂时无数据可读,可以继续读,或者等待epoll或select的后续通知。(EAGAINE,EWOULDBLOCK产生的原因:可能是多进程读同一个sockfd,可能一个进程读到数据,其他进程就读取不到数据(类似惊群效应),当然单个进程也可能出现这种情况。对于这种错误,不需用close(sockfd)。可以等待select或epoll的下一次触发, 继续读。),这里有一点需要说明的是当采用epoll的边沿触发模式时,必须一次性将缓冲区的数据全部读完,即读到errno == EAGAINE 为止。
       ② 如果   errno   为  EINTR
            表示被中断了,可以继续读,或者等待epoll或select后续的通知。
            否则,真的是读取数据失败。(此时应该close(sockfd))

2、send和sendto      
    返回值是实际发送的字符数,因为我们知道要发送的总长度,所以,如果没有发送完,我们可以继续发送。
      <0   当返回值为-1时,我们需要判断 errno:
            ① 如果errno为  EAGAINE   或 EWOULDBLOCK ,表示当前缓冲区写满,可以继续写,
                  或者等待epoll或select的后续通知,一旦发送缓冲区由满变为不满,就会触发写操作,这个也是经常利用的一个特性。  
            ② 如果errno为EINTR  ,表示被中断了,可以继续写,或者等待epoll或select的后续通知。
                   否则真的出错了,即 errno 不为 EAGAINE 或 EWOULDBLOCK 或 EINTR,此时应该close(sockfd)
      >=0  >=0且不等于要求发送的长度,应该继续send直到发送完毕,如果等于要求发送的长度,发送完毕。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值