net_send 发送数据函数 int net_send(int sockfd, struct timeval timeout, char *mem, unsigned int len) { unsigned int byte_count = 0; int n; 使用 poll 函数检测 pfd 上的事件,关心的是 POLLOUT 事件也就是数据可写的事件,超时时间为 1ms: struct pollfd pfd[1]; pfd[0].fd = sockfd; pfd[0].events = POLLOUT; int rv = poll(pfd, 1, 1); 设置超时,这里的 timeout 在 send_over_network|fuzz 中是 1ms。 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); 如果存在可写事件且可写事件为 POLLOUT 时,向目标发送数据。 if (rv > 0) { if (pfd[0].revents & POLLOUT) { while (byte_count < len) { usleep(10); n = send(sockfd, &mem[byte_count], len - byte_count, MSG_NOSIGNAL); if (n == 0) return byte_count; if (n == -1) return -1; byte_count += n; } } } return byte_count; } net_recv 接收数据函数 int net_recv(int sockfd, struct timeval timeout, int poll_w, char **response_buf, unsigned int *len) { char temp_buf[1000]; int n; struct pollfd pfd[1]; pfd[0].fd = sockfd; pfd[0].events = POLLIN; int rv = poll(pfd, 1, poll_w); setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); // data received if (rv > 0) { if (pfd[0].revents & POLLIN) { n = recv(sockfd, temp_buf, sizeof(temp_buf), 0); if ((n < 0) && (errno != EAGAIN)) { return 1; } while (n > 0) { usleep(10); *response_buf = (unsigned char *)ck_realloc(*response_buf, *len + n + 1); memcpy(&(*response_buf)[*len], temp_buf, n); (*response_buf)[(*len) + n] = '\0'; *len = *len + n; n = recv(sockfd, temp_buf, sizeof(temp_buf), 0); if ((n < 0) && (errno != EAGAIN)) { return 1; } } } } else if (rv < 0) // an error was returned return 1; // rv == 0 poll timeout or all data pending after poll has been received successfully return 0; }