HTTP连接管理

我们在平时的开发过程中,网络请求一般使用HTTP,当然,为了安全性考虑,现在几乎都在使用HTTPS了。但是,我们始终是有必要去了解HTTP的连接管理,因为HTTPS只是在HTTP的基础上增加了安全层。这篇博客主要是讲解的HTTP相关的知识,如果对HTTPS的通信感兴趣的同学,可以查看我的另一篇博客【“攻城狮” 需要了解的密码知识】,里面最后的内容就是讲解的HTTPS相关的知识。

1. HTTP协议栈

HTTP要传送一条报文时,会以流的形式将报文数据的内容通过一条打开的TCP连接按序传输。TCP收到数据流之后,会将数据流分割成小的数据段,并将段封装在IP分组中,通过因特网进行传输。所有这些工作都是由 TCP/IP 软件来处理的。
大致的网络协议栈结构图如下:
在这里插入图片描述
从上图可以看出,HTTP是依赖于TCP进行传输的,所以HTTP的连接本质上是TCP的连接。IP地址可以将你连接到正确的计算机,而端口号则可以将你连接到正确的应用程序上去。TCP连接是通过4个值来识别的:
<源 IP 地址、源端口号、目的 IP 地址、目的端口号>

2. HTTP连接

我们知道,HTTP在进行网络传输之前,有一个连接的过程,这个过程就是三次握手;而在通信完毕,不需要连接的时候,为了不浪费连接资源,会有四次挥手的操作。

2.1 三次握手

在这里插入图片描述

  1. CLOSED: 表示初始状态。
  2. LISTEN: 服务端的某个SOCKET处于监听状态,可以接收连接了。
  3. SYN_SENT: 表示客户端已发送SYN报文。
  4. SYN_RCVD: 表示服务端接收到了SYN报文。
  5. ESTABLISHED: 表示连接已经建立。

三次握手的具体流程:

  1. 请求新的TCP连接时,客户端要向服务端发送一个小的TCP分组(通常是40 ~ 60 个字节)。 这个分组中设置了一个特殊的SYN(Synchronize Sequence Numbers)标记,说明这是个连接请求 [这里客户端的SYN记为 J]。
  2. 如果服务器接收了连接,就会对一些连接参数进行计算,并向客户端回送一个TCP分组,这个分组中的SYN和ACK(Acknowledgement)标记都被置位,说明连接请求已被接收 [这里服务端的SYN记为 K,而ACK是服务端利用客户端传递过来的J基础上面加1得到的]。
  3. 最后,客户端向服务端回送一条确认消息,通知它连接已成功建立 [这里的ACK是客户端利用服务端传递过来的K基础上面加1得到的]。

通过上面的三次握手,客户端就与服务端建立了连接,后面就可以进行数据的传输通信了。需要注意的是:现代的TCP栈都允许客户端在第三步确认连接的时候,同时在这个连接中发送数据。

为什么是三次握手,两次不行吗?
从上面的分析,我们可以看出,HTTP的握手连接需要进行三步操作。而其实经过前面两步握手操作之后,客户端与服务端就已经确认了通信的双方,完全可以不需要第三步的确认操作。
现假定出现一种异常情况,即客户端发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以至于延误到释放以后的某个时间才到达服务端。本来这是一个早已失效的报文段,但服务端收到以后,误以为是客户端又发出一次新的连接请求。于是就向客户端发出确认报文段,同意建立连接。假定不采用三次握手,那么只要服务端发出确认,新的连接就建立了。由于现在客户端并没有发出建立连接的请求,因此不会理睬服务端的确认,也不会向服务端发送数据。但服务端却以为新的连接建立了,并一直等客户端发来数据,服务端的许多资源就浪费了。

2.2 四次挥手

在这里插入图片描述

  1. ESTABLISHED: 表示连接处于建立状态。
  2. FIN(Finish): 表示客户端发送了FIN报文,通知服务端通信结束,断开连接。
  3. ACK: 表示服务端确认收到了断开连接的请求,并告知客户端。
  4. FIN(Finish): 表示服务端发送了FIN报文,通知客户端通信结束,断开连接。
  5. ACK: 表示客户端确认收到了断开连接的请求,并告知服务端。

上图中的
FIN_WAIT_1:客户端自己发出FIN请求至得到服务端的ACK响应这段时间的等待。
FIN_WAIT_2:客户端在收到服务端的ACK和FIN两个响应这段时间的等待。
CLOSE_WAIT:服务端连发了两个响应(ACK、FIN)给客户端。
FIN_WAIT:服务端自己发出FIN请求到得到客户端的ACK响应这段时间的等待。
CLOSED: 表示连接彻底关闭了。

四次挥手的具体流程:

  1. 当客户端的应用程序通知TCP数据已经发送完毕时,TCP向服务端发送一个带有FIN标记的报文段。
  2. 当服务端收到这个FIN报文段之后,并不立即用FIN报文回复客户端,而是先向客户端发送一个确认序号ACK,同时通知自己相应的应用程序,对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN)。
  3. 服务端的应用程序告诉TCP:我要彻底关闭连接,TCP向客户端发送FIN。
  4. 客户端收到这个FIN后,向服务端发送一个ACK,表示连接彻底释放。

3. HTTP长连接

HTTP请求是 “无记忆” 的,也就是说下一次请求不知道上一次请求发生了什么;所以出现了session,cookie等技术来实现状态保持。默认情况下,一次请求响应结束之后,就会断开连接了;下次进行请求的话,又会重新建立HTTP连接。而实际情况下,连接所耗费的时间比数据通讯的时间更长,所以出现了长连接(Keep-Alive)机制。也就是这次请求完成之后,并不会立刻断开连接,保持一段时间,如果在保持的时间范围内,下次过来的请求就不会重新建立连接过程,而是直接的进行数据通讯,这样就大大的提升了网络请求的效率。

实现Keep-Alive连接的客户端可以通过包含Connection: Keep-Alive首部请求将一条连接保持在打开状态。如果服务端愿意为下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有Connection: Keep-Alive首部,客户端就认为服务端不支持Keep-Alive,会在发回响应报文之后关闭连接。

在这里插入图片描述
Keep-Alive 首部只是请求将连接保持在活跃状态。发出Keep-Alive请求之后,客户端和服务器并不一定会同意进行Keep-Alive会话。它们可以在任意时刻关闭空闲的Keep-Alive连接,并可随意限制Keep-Alive连接所处理事务的数量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋恨雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值