![](/img/trans.png)
[英]C socket HTTP 1.1 persistent connection when should server close the socket?
[英]Persistent Connection on a web server HTTP1.1
我正在尝试使用HTTP1.1协议在Linux下用C编写Web服务器。 我已经使用了select来处理多个请求,但我想实现持久连接,但到目前为止还没有成功,因为我无法正确设置超时时间。 我该怎么做? 我想到了setsockopt函数:
setsockopt(connsd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))
其中tv是一个struct timeval。 这也不起作用。
有什么建议么?
最简单的解决方案可能是保留每个连接的上次请求请求,然后定期检查该时间,如果时间过长,则关闭连接。
SO_RCVTIMEO
仅在实际读取数据时才起作用。 select()
不会兑现它。 select()
在其最后一个参数中带有一个超时参数。 如果您有一个计时器数据结构来组织哪些连接应该以什么顺序超时,则可以将最快的超时时间传递给select()
。 如果返回值为0,则表示发生了超时,您应该使所有超时的连接失效。 处理活动连接(并在计时器数据结构中重新设置其空闲超时)之后,应再次检查是否有任何连接超时,然后再次调用select()
。
您可以使用多种数据结构,但流行的数据结构包括定时轮和计时器堆。
计时轮基本上是一个组织为圆形缓冲区的数组,其中每个缓冲区位置代表一个时间单位。 如果车轮单位是秒,则可以构造一个300元素的数组来表示5分钟的时间。 有一个粘性索引,表示任何计时器最后一次到期,并且当前位置将是当前时间与数组大小的乘积。 要添加超时,请计算需要超时的绝对时间,并根据数组的大小对其进行取模,然后将其添加到该数组位置的列表中。 最后一个索引和当前位置之间的所有存储桶(其超时时间已到)都需要过期。 条目到期后,最后一个索引将更新到当前位置。 为了计算直到下一次到期的时间,将从当前位置开始扫描各个存储桶,以查找具有将要到期的条目的存储桶。
计时器堆基本上是优先级队列,其中较早到期的条目的优先级高于较晚到期的条目的优先级。 非空堆的顶部确定下一次到期的时间。
如果您的应用程序一直都在插入很多计时器,然后一直取消它们,那么轮可能会更合适,因为插入到轮中和从轮中卸下比从轮中插入和拆卸更有效。优先级队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.