c语言实现发送doip消息后,启动计时,在一定时间内收到回复 则计时取消,如果超时报超时错误
时间: 2024-03-26 18:39:38 浏览: 102
实现这个功能的方法可以是使用 `select` 函数进行超时等待,具体步骤如下:
1. 发送 DOIP 消息
2. 设置超时时间,例如 5 秒钟
3. 使用 `select` 函数进行等待,同时监听套接字是否有数据可读
4. 如果在超时时间内有数据可读,则取消计时,处理接收到的数据
5. 如果超时时间到了仍然没有数据可读,则报超时错误
下面是一个简单的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_ADDR "127.0.0.1"
#define SERVER_PORT 12345
#define TIMEOUT_SEC 5
int main(int argc, char *argv[])
{
int sockfd, ret;
struct sockaddr_in server_addr;
struct timeval timeout = {TIMEOUT_SEC, 0};
fd_set readfds;
char buf[256];
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
server_addr.sin_port = htons(SERVER_PORT);
// 发送 DOIP 消息
// ...
// 设置超时时间
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
// 等待数据或超时
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
ret = select(sockfd + 1, &readfds, NULL, NULL, &timeout);
if (ret == 0) {
fprintf(stderr, "timeout\n");
exit(EXIT_FAILURE);
} else if (ret < 0) {
perror("select");
exit(EXIT_FAILURE);
}
// 有数据可读,取消超时计时,处理接收到的数据
if (FD_ISSET(sockfd, &readfds)) {
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, NULL, 0); // 取消超时计时
memset(buf, 0, sizeof(buf));
ret = recv(sockfd, buf, sizeof(buf), 0);
if (ret < 0) {
perror("recv");
exit(EXIT_FAILURE);
} else {
printf("Received: %s\n", buf);
}
}
// 关闭套接字
close(sockfd);
return 0;
}
```
需要注意的是,`select` 函数可能会因为其他套接字上的事件而提前返回,因此需要使用 `FD_ISSET` 函数判断是否是目标套接字上的事件。另外,在取消超时计时时,需要将 `SO_RCVTIMEO` 选项设置为 NULL。
阅读全文