HTTP基础之七(连接Connection关闭的奥秘)

连接关闭的随意性

首先我们需要知道,任何HTTP客户端,服务器,代理可以在任何时候关闭TCP连接。当服务器端关闭连接时,不知道客户端可能需要在此时发送请求,这次如果出现客户端发起请求就会报错。

 

Content-Length和Truncation(截断)

每一个HTTP响应都应该精确的给出消息的大小,把这个值写到Content-Length头里面,有些旧的服务器会给出错误的值,这时只能依靠实际连接末尾的数据来判断。当客户端或代理接收到服务器响应时,连接中断,并且发现Content-Length和实际接收到的数据大小不一致,这时接收方应该询问正确的长度是多少。如果接收方是一个缓存代理,不应该换成错误的消息而是原封不动的转发出去。

 

连接关闭容错,重试,和幂等性

HTTP应用必须相当的处理异常的关闭,客户端在执行事务过程中,连接关闭,应该在此次请求没有任何副作用的情况下重试一次。例如GET请求没有任何副作用,请求多次都是一样的。但是如果是POST请求则不能随便重试,一般浏览器的处理就是弹出一个对话框然用户选择是否重新提交。客户端可以针对幂等性的请求(GET,HEAD,PUT,DELETE,TRACE,OPTIONS)进行重试,所谓幂等性就是每次请求都和第一次请求效果一样。非幂等性的请求(POST)不能被自动重试。

 

优雅关闭连接

TCP连接是双向的,每个端点即是发送方(发送队列)也是接收方(接收队列)。如图所示:

TCP全关闭和半关闭:应用程序同时关闭out和in两个通道成为全关闭,关闭其中之一为半关闭。

简单的应用程序可以使用全关闭,但是对于复杂的多个客户端,代理服务器连接时,需要使用半关闭来避免异常出现。

一般情况下,关闭输出的通道是安全的,关闭接收的通道会有风险,因为关闭时对方还在发送数据,此时操作系统抛出一个“连接被重置”的错误。并且会擦除还没有读取的数据,这个在管线连接里面会带来更大的危害。

怎么做到优雅关闭呢?

首先关闭output通道,然后等待另外一端也关闭output通道,这意味着双方都不会再发送任何消息。这时再关闭input通道,就不会产生错误。当然不能保证都实现对等的关闭,程序需要关闭output通道,并且定期检查input通道。如果在超出一段时间input通道没有关闭,则强制关闭。怎么说呢?我的input就是对方的output,尽量从发送的一端来关闭才是安全的。

作者:张雪飞
出处:https://zhangxuefei.site/p/1061
版权说明:欢迎转载,但必须注明出处,并在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

发表评论

电子邮件地址不会被公开。 必填项已用*标注