linux中send函数MSG_NOSIGNAL

linux下当连接断开,还发数据的时候,不仅send()的返回值会有反映,而且还会向系统发送一个异常消息,如果不作处理,系统会出BrokePipe,程序会退出,这对于服务器提供稳定的服务将造成巨大的灾难。为此,send()函数的最后一个参数可以设MSG_NOSIGNAL,禁止send()函数向系统发送异常消息

//中间的select就是为了侦测断开后再次连接并二次send

int socket_send(async_socket_t* async_sock, uint8_t* buf, int len){
  uint8_t* ptr = buf;
  int left = len;
  int rc;
  while (left > 0) {
#ifdef __IOS__
    rc = send(async_sock->fd, ptr, left, 0);
#else
    rc = send(async_sock->fd, ptr, left, MSG_NOSIGNAL);
#endif


    if(rc>0){
      left -= rc;
      ptr += rc;
    }else if (rc<0) {
      if (errno == EAGAIN) {
        break;
      } else if (errno == EINTR) {
        continue;
      } else {
        printf("send step 1 failed\n");
        return -1;
      }
    }
  }

  if(left>0){
    printf("wait writeable");
    fd_set writeset;
    FD_ZERO(&writeset);
    int max_fd = async_sock->fd + 1;
    struct timeval timeout;
    while(!async_sock->bstop && left>0){      
      timeout.tv_sec = 0;
      timeout.tv_usec = 100*1000;
      FD_SET(async_sock->fd, &writeset);
      int ret = select(max_fd, NULL, &writeset, NULL, &timeout);
      if( ret == 0){//TIMEOUT
        continue;
      }else if( ret < 0){
        printf("select failed\n");
        if(errno == EINTR){
          continue;
        }
        return -1;
      }
      //writeable
#ifdef __IOS__
      rc = send(async_sock->fd, ptr, left, 0);
#else
      rc = send(async_sock->fd, ptr, left, MSG_NOSIGNAL);
#endif

      if(rc>0){
        left -= rc;
        ptr += rc;
      }else if (rc<0) {
        printf("send step 2 failed\n");
        return -1;
      }
    }

  }
  return len-left;
}

猜你喜欢

转载自blog.csdn.net/yuanchunsi/article/details/79745619