gpt4 book ai didi

C:写一个适当的超时

转载 作者:太空宇宙 更新时间:2023-11-04 04:50:07 24 4
gpt4 key购买 nike

在仔细搜索资源后,我仍然不完全确定如何在 C 中编写正确且可用的计时器函数。我没有使用线程(或可并行化代码)。我只是想编写一个秒表函数,我可以用它在经过一小段时间后触发一些代码。

这是计时器的一种非常常见的用法,在“超时”的情况下,我设置了一个客户端-服务器,客户端正在发送一些数据(UDP 样式与 sendto(...) 和从(...)接收)。我已经编写了我的系统,以便客户端在我定义的数据包结构中发送一大块数据,服务器通过 CRC 处理它,然后发回一个确认数据包 (ACK),表明消息未被损坏。但是,我想实现一个超时,如果客户端在一段时间内没有收到 ACK,则客户端重新发送数据 block (当然服务器被设置为检查重复项)。我想在客户端中嵌套这段计时器代码,出于某种原因,我认为这应该不是那么困难。

我从很久以前完成的工作中挖掘出旧的信号处理代码,因为这似乎是我通常认为提到的唯一解决方案,有人可以指导我如何使用以下信号处理代码不仅可以接收定时信号,还可以触发某种 Action 。从概念上讲,我觉得它会是:“发送数据,启动定时器,定时器到期后执行重新发送,重置定时器......重复直到收到 ACK”。更好的是,这将是编写计时器函数的一种更简单的方法,但鉴于 C 是一种低级语言,看起来希望不大....

#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>

extern char *strsignal(int sig);

void timer_handler(int a)
{
// handle signal
printf(">>>> signal caught\n");
printf(">>>> int parameter = %s\n", (char*) strsignal(a));
}

int main(int argc, char* argv[])
{
int retval;
struct itimerval timerValue;
struct itimerval oldTimerValue;
struct sigaction action;

action.sa_handler = &timer_handler;
action.sa_flags = SA_NODEFER;

// initialize timer parameters: expires in 5 seconds
timerValue.it_interval.tv_sec = 5;
timerValue.it_interval.tv_usec = 0;

timerValue.it_value.tv_sec = 5;
timerValue.it_value.tv_usec = 0;

// install signal handler to catch SIGALRM
//signal(SIGALRM, timer_handler);
sigaction(SIGALRM, &action, NULL);

retval = setitimer(ITIMER_REAL, &timerValue, &oldTimerValue);

if (-1 == retval)
perror("Could not set timer");

while(1);

return 0;
}

最佳答案

Xymostech 提供了我需要的确切功能,在查阅了“select”的 API 之后,其中包括一个小的使用示例,我修改了那里的代码以适应我的需要并编写了一个套接字计时器(对于读取,那些非常简单扩展到写入等,因为“select”有启用这种检查的参数)。确保您已包含“选择”API 指定的以下库:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>

以下是我根据 API 示例创建的 waittoread(...) 函数,运行良好。这在我的特定问题领域工作得很好,但是,如果有人正在寻找一个更通用的计时器(即不仅仅是用于计时套接字读写或文件描述符)请引用信号处理(有点本着代码的精神我发布在我最初的问题中)。

#define S1READY 0x01 // necessary for the function's bitwise OR operation
int waittoread(int s1, int timeout_value){
fd_set fds; // create set of sockets to be waited on
struct timeval timeout; // the time-out value
int rc; // # of sockets that are ready before timer expires
int result;

/* Set time limit. */
timeout.tv_sec = timeout_value;
timeout.tv_usec = 0;
/* Create a descriptor set containing the socket. */
FD_ZERO(&fds); // MACRO to reset the socket storage set so new ones can be added
FD_SET(s1, &fds); // add the socket descriptor into the socket set to wait on
rc = select(sizeof(fds)*4, &fds, NULL, NULL, &timeout); // build the socket-wait system
// another way of calling select that would be a better approach:
// rc = select(s1 + 1), &fds, NULL, NULL, &timeout);
if (rc==-1) {
perror("Error: Call to select failed.");
return -1;
}
result = 0;
if (rc > 0){
if (FD_ISSET(s1, &fds)) result |= S1READY; // if the result is non-zero, perform a BIT-wise OR to extract the true socket count #
}
return result;
}

关于C:写一个适当的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16381827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com