Web服务器HTTP1.1上的持久连接

时间:2013-06-21 16:54:51

标签: c http connection timeout persistent

我正在尝试使用协议HTTP1.1在Linux下用C编写Web服务器。 我已经将select用于多个请求,我想实现持久连接但是到目前为止它没有工作,因为我无法正确设置超时。我该怎么做?我想一下setsockopt函数:

setsockopt(connsd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))

其中tv是结构时间。这也不起作用。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

最简单的解决方案可能是为每个连接保留最后一次请求,然后定期检查时间以及是否很久以前关闭连接。

答案 1 :(得分:1)

SO_RCVTIMEO仅在您实际阅读数据时才有效。 select()不会尊重它。 select()在其最后一个参数中使用超时参数。如果您有一个计时器数据结构来组织哪些连接应按什么顺序超时,那么您可以将最快的时间传递给select()的超时时间。如果返回值为0,则表示发生超时,您应该使所有超时连接失效。在处理实时连接(并在计时器数据结构中重新设置其空闲超时)之后,您应该再次检查是否应该超时,然后再次调用select()

您可以使用各种数据结构,但常用的数据结构包括计时轮和计时器堆。

定时轮基本上是一个组织为循环缓冲区的数组,其中每个缓冲区位置代表一个时间单位。如果轮单位是几秒钟,您可以构造一个300元素数组来表示5分钟的时间。有一个粘性索引,表示任何计时器的最后一次到期,当前位置将是以数组大小为模的当前时间。要添加超时,请计算需要超时的绝对时间,以数组的大小为模,然后将其添加到该数组位置的列表中。最后一个索引与已达到超时的当前位置之间的所有存储桶都需要过期。在条目到期后,最后一个索引将更新为当前位置。要计算下一次到期之前的时间,将从当前位置开始扫描存储桶,以查找具有将过期的条目的存储桶。

计时器堆基本上是一个优先级队列,其中较早到期的条目的优先级高于稍后到期的条目。非空堆的顶部确定下一次到期的时间。

如果您的应用程序一直在插入大量的定时器,然后一直取消它们,那么轮子可能更合适,因为插入轮子并从轮子上取下比插入和更有效从优先级队列中删除。