但是 我还没运行到 检测信号的地方 还被阻塞在 recvfrom 里面
时间: 2024-03-21 12:38:09 浏览: 52
是的,如果程序还没有运行到检测信号的地方,recvfrom 函数会一直阻塞,等待数据到来。为了解决这个问题,可以使用 select 函数来监视套接字的状态,并设置一个超时时间,确保程序不会永久阻塞在 recvfrom 函数中。
具体操作如下:
1. 将套接字设置为非阻塞模式,例如:
```
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
```
2. 使用 select 函数来监视套接字的状态,例如:
```
fd_set readfds;
struct timeval timeout;
while (1) {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
timeout.tv_sec = 5; // 超时时间为 5 秒
timeout.tv_usec = 0;
int ret = select(sockfd + 1, &readfds, NULL, NULL, &timeout);
if (ret == -1 && errno == EINTR) {
// 如果 select 函数被信号中断,需要重新进行监视
continue;
} else if (ret == -1) {
// 如果 select 函数返回其他错误,需要进行错误处理
break;
} else if (ret == 0) {
// 如果 select 函数返回超时,说明没有数据到来
// 可以在这里进行其他处理
continue;
} else {
// 如果 select 函数返回套接字可读,说明数据已经到来
if (FD_ISSET(sockfd, &readfds)) {
char buf[1024];
int len = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen);
if (len == -1 && errno == EWOULDBLOCK) {
// 如果 recvfrom 函数返回 EWOULDBLOCK 错误,说明没有数据到来
// 可以在这里进行其他处理
continue;
} else if (len == -1) {
// 如果 recvfrom 函数返回其他错误,说明出现了错误,需要进行错误处理
break;
} else {
// 如果 recvfrom 函数返回接收到的数据的长度,说明数据已经到来
// 可以在这里处理接收到的数据
}
}
}
// 检查是否接收到了中断信号,如果接收到了就退出循环
if (signal_received) {
break;
}
}
```
这样,如果没有数据到来,select 函数会在超时时间内返回,然后可以进行其他处理。如果有数据到来,select 函数会返回套接字可读,并进入循环体中接收数据。同时,在循环中检查 signal_received 标志,如果标志为真,就会退出循环,从而中断 recvfrom 函数。
阅读全文