如何判断使用 keep-alive 的 HTTP 连接传输数据已经完成?

2015-08-02 22:35:11 +08:00
 mason961125

正在做一个HTTP代理,然而现在大部分的HTTP都使用了keep-alive,也就导致连接是一直开启并不close。然而我应该如何判断数据已经传输完成呢?
目前我是用了一个checker来对每个连接进行timeout检验,超过规定的时间就认定传输已完成。
所以,有更好的方法么?

5009 次点击
所在节点    HTTP
12 条回复
wkdhf233
2015-08-02 22:40:35 +08:00
HTTP协议不是有结束界定的吗
GET的话俩回车,POST之类的到达Content-Length。。
zado
2015-08-02 22:47:28 +08:00
看那个Content-Length,这个数值加上http头大小就是全部数据的大小了。我也是定时检测,然后超过一定时间的就断开。
imn1
2015-08-02 22:50:18 +08:00
@wkdhf233
NO
socket 没断开的话,keep-alive 期内可以多次请求
我写过一个爬虫就是用一次connect连续多次获取,定时断开
不过对http1.0没用,网站那边需要至少1.1
mason961125
2015-08-02 22:53:32 +08:00
@zado 虽然是个HTTP代理,但是遇到HTTPS的请求也是可以代理的。但是如果是HTTPS请求的话,是没办法知道请求头的吧(我记不太清楚了,错了求指正
mason961125
2015-08-02 22:54:28 +08:00
@imn1 但是我又怕如果是看YouTube那种的长连接,在连接时间里数据基本一直在传输的,就无解了。
wkdhf233
2015-08-02 23:27:03 +08:00
@imn1 同个socket多次请求,单次的结束界定你也得按协议规定来啊,你还能把俩GET挤到一起发出去?
长连接是socket层面的东西,HTTP协议层面除了个keep-alive之外没啥变化的
imn1
2015-08-02 23:28:43 +08:00
没做过proxy,不过个人觉得杀掉 http 就可以了
ssl 网站那边出于安全性和服务器性能,会有检查断开的机制
定时检查连接数量,把时间较长和“不合理”的长连接强制断开就行了
imn1
2015-08-02 23:39:43 +08:00
@wkdhf233
不是同时,是依次
你可以自己写一个测试一下,根据字节或结束符判断传输完毕,保存或处理,不发送close,然后send另一个http请求,会有新的返回的
反正我写过,较好的服务器连续请求5个不同url(当然服务器是同一个)成功,很多时候第6个请求失败(有些服务器线路不好的2~3个就不行了),但我的 socket 知识水平有限,异常处理得不好,所以没能继续写
wkdhf233
2015-08-03 00:15:24 +08:00
@imn1 =_=长连接的程序我写过,因为PHP不好多线程所以一次把40+个请求送出去再慢慢处理返回,复用长连接本来也是十分常见的做法。

我说的是,socket保持和HTTP协议的结束判断没有关系。socket只是承载传输,协议才是描述请求。要判断一个HTTP请求是否结束,只用根据协议的分割划分来就行。
请求和请求间按照协议规定划分,而要是某个请求里没有keep-alive了,说明这个socket不用保持了。
楼主担忧一个长连接照协议保持着但实际上没有作用了是多余的,不用了掐掉这是连接方的责任,还保持着就说明它还有可能传东西。

代理方要做的只是统一设置一个超时时间,超过时间未活动(注意是未活动,每个带keep-alive的请求都应该清零计数器)的连接都掐掉就行了。
zado
2015-08-03 00:25:07 +08:00
https 应该是没办法知道请求头的,所以应该也没有办法做代理吧,除非就是做成路由器那样的直接转发数据,那样就只能是在数据经过的时候记录一下时间,超过多长时间没有数据经过了就断开。
loggerhead
2015-08-03 00:38:35 +08:00
http 0.9或1.0 每次请求完成都会直接断开连接,并视为数据传完。
1.1如果没有connection: close就会被认为是keep-live。如果服务器主动断开连接,需要在响应报文中设置connection: close,否则tcp连接处于半关闭,客户端发的数据服务器照样接收,但是不进行任何处理。
不知道楼主是想问 如何判断还有没有请求,还是如何判断请求有没有传完?
前者没法判断,后者得分析报文。
julyclyde
2015-08-03 13:55:50 +08:00
content-length或者chunked的尾0报 代表一个HTTP body的结束
如果是没有body的,header行后面多加一个回车就算完

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/210305

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX