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; }