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

 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的下一次触发, 继续读。)
       ② 如果   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,如果等于要求发送的长度,发送完毕。

你可能感兴趣的:(socket编程,linux系统接口)