c - 如何在网络程序中监视/关闭待处理的网络 session

标签 c linux timer network-programming

我正在编写类似下面的内容(直径协议(protocol)),我需要实现一个计时器来监视 session 挂起状态并在 session 超过某个阈值时终止它们,最好的方法是什么?

请注意,我正在寻找算法。

Credit-Control Application Related Parameters
Tx timer

When real-time credit-control is required, the credit-control
client contacts the credit-control server before and while the
service is provided to an end user.  Due to the real-time nature
of the application, the communication delays SHOULD be minimized;
e.g., to avoid an overly long service setup time experienced by
the end user.  The Tx timer is introduced to control the waiting
time in the client in the Pending state.  When the Tx timer
elapses, the credit-control client takes an action to the end user
according to the value of the Credit-Control-Failure-Handling AVP
or Direct-Debiting-Failure-Handling AVP.  The recommended value is
10 seconds.

最佳答案

您根本不需要计时器。

当您的应用程序使用例如接受新连接时accept() ,您可以使用例如记录当前时间clock_gettime() (特别是使用 CLOCK_BOOTTIME 时钟,这需要 2.6.39 或更高版本的内核)。

在处理过程中,特别是在发送任何响应之前,您的代码必须检查连接(时间戳)是否太旧。

虽然实现起来非常简单,而且非常精确,但 clock_gettime() 调用并不是特别快。也就是说,它本身并不是一个缓慢的调用 - 没有更快的方法来获取当前时间 - 只是根据当前时间检查时间戳确实需要每次调用一次 clock_gettime()一次,可能会导致生成大量此类调用。

如果性能比精度更重要,可以使用定时器中断。定时器中断指定的时间间隔后发生;他们可能会被推迟。换句话说,虽然定时器中断在间隔过去之前不应该触发,但它们可以在之后的任何时间触发。因此,超时并不像上面那么严格。

当计时器到时,信号处理程序会设置一个连接/超时特定标志。您的函数不是检查时间戳,而是验证该标志是否尚未设置。

由于 Linux 中的计时器是有限的资源(并不稀缺,只是可能限制为少于可能的并发客户端连接数)——限制约为 getrlimit(RLIMIT_SIGPENDING) ,在我的机器上大约有四万——我建议不要使用timer_create()为每个连接创建一个单独的计时器。或timerfd_create() .

相反,我会使用实时信号(例如 SIGRTMIN+1)和 sigwaitinfo() 上循环的(高优先级)线程。 ,信号在所有其他线程中被阻塞,维持下一个超时事件。当 sigwaitinfo() 调用返回时,它还会注册新的超时事件;这样,任何线程都可以通过创建合适的结构,将其添加到链或数组中,然后引发实时信号来添加新的超时事件。 siginfo_t 结构(参见sigaction()的定义)告诉我们信号是由定时器生成的还是通过例如定时器发出的。 sigqueue() .

一般来说,使用定时器中断通常是首选,因为它比反复将时间戳与当前时间进行比较的开销更少,而且大多数应用程序并不关心超时是否有点晚(只要它永远不会)太早了)。特别是,十秒超时对于一个客户端可能是 10.0 秒,对于另一个客户端可能是 10.1 秒。

很难说超时对于您的情况是否应该准确。您引用的规范似乎强调最小延迟,而精确的超时(甚至所有客户端的超时相同)似乎并不那么重要。我个人的意见倾向于使用定时器中断。

无论您选择哪种超时处理方法,我建议您从一开始就将超时处理设计到逻辑中。在这两种情况下,您的代码都需要定期检查连接是否超时;一种方法只是将当前时间与原始时间戳进行比较,另一种方法是一个标志。只要您设计了超时检查,您就不太可能错过任何需要检查超时条件的地方,以实现稳健可靠的操作。

希望这有帮助。

关于c - 如何在网络程序中监视/关闭待处理的网络 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18855908/

相关文章:

C、用for循环初始化二维数组

C代码运行时崩溃

linux - 在 Dockerfile 中使用 wget 时如何自动回答 'Yes'?

linux - 使用通配符复制

bash - 如何在 bash 中创建秒表?

c - 现在实现平板分配器值得吗?

c++ - 检查 R 函数是否依赖于 C/C++ 编译代码的函数?

linux - 为 EC2 Amazon Linux 实例设置 SFTP Sublime Text 3

android - 在对话框之间显示 ProgressDialog

java - 秒表取消暂停不起作用