c语言 read 超时
时间: 2023-06-23 07:52:05 浏览: 294
C语言附带超时功能的system函数,windows版本。
5星 · 资源好评率100%
在 C 语言中,可以使用 `select()` 函数来实现读取数据时的超时操作。`select()` 函数可以同时监视多个文件描述符,如果其中的某个文件描述符变为“可读”,则 `select()` 函数就会返回。我们可以利用这一特性,在 `select()` 函数的超时时间内等待数据的到来,如果超时时间到了但数据还未到来,则认为读取超时。
以下是一个示例代码,演示了如何使用 `select()` 函数实现读取数据时的超时操作:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#define TIMEOUT_SEC 5 // 超时时间(秒)
#define BUF_SIZE 1024 // 缓冲区大小
int main(int argc, char *argv[])
{
int sockfd;
struct timeval timeout;
fd_set rset;
char buf[BUF_SIZE];
int ret, n;
// 创建 socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置非阻塞模式
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
// 连接服务器
// ...
// 等待数据到来
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
timeout.tv_sec = TIMEOUT_SEC;
timeout.tv_usec = 0;
ret = select(sockfd + 1, &rset, NULL, NULL, &timeout);
if (ret < 0) {
perror("select failed");
exit(EXIT_FAILURE);
} else if (ret == 0) {
printf("read timeout\n");
exit(EXIT_SUCCESS);
} else {
if (FD_ISSET(sockfd, &rset)) {
n = read(sockfd, buf, BUF_SIZE);
if (n < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
printf("read would block\n");
} else {
perror("read failed");
}
} else if (n == 0) {
printf("connection closed\n");
} else {
printf("read %d bytes: %.*s\n", n, n, buf);
}
}
}
close(sockfd);
exit(EXIT_SUCCESS);
}
```
在上述代码中,我们使用 `select()` 函数等待 sockfd 的可读事件,等待时间为 `TIMEOUT_SEC` 秒。如果在等待时间内 sockfd 变为“可读”,则调用 `read()` 函数读取数据。如果 `read()` 函数返回 0,表示连接已经关闭;如果 `read()` 函数返回负值,可以通过判断 `errno` 是否为 `EWOULDBLOCK` 或 `EAGAIN` 来判断是否读取超时。如果 `read()` 函数返回正值,则表示读取到了数据。
阅读全文